1// kernel_interface.cpp 2 3#include <KernelExport.h> 4#include <fsproto.h> 5 6#include "Debug.h" 7#include "FileSystem.h" 8#include "String.h" 9#include "UserlandFS.h" 10#include "Volume.h" 11 12#if USER 13 14// disable_interrupts 15static inline 16cpu_status 17disable_interrupts() 18{ 19 return 0; 20} 21 22// restore_interrupts 23static inline 24void 25restore_interrupts(cpu_status status) 26{ 27} 28 29#endif // USER 30 31// #pragma mark - 32// #pragma mark ----- prototypes ----- 33 34extern "C" { 35 36// fs 37static int userlandfs_mount(nspace_id nsid, const char *device, ulong flags, 38 void *parameters, size_t len, void **data, vnode_id *rootID); 39static int userlandfs_unmount(void *ns); 40static int userlandfs_initialize(const char *deviceName, void *parameters, 41 size_t len); 42static int userlandfs_sync(void *ns); 43static int userlandfs_read_fs_stat(void *ns, struct fs_info *info); 44static int userlandfs_write_fs_stat(void *ns, struct fs_info *info, long mask); 45 46// vnodes 47static int userlandfs_read_vnode(void *ns, vnode_id vnid, char reenter, 48 void **node); 49static int userlandfs_write_vnode(void *ns, void *node, char reenter); 50static int userlandfs_remove_vnode(void *ns, void *node, char reenter); 51 52// nodes 53static int userlandfs_fsync(void *ns, void *node); 54static int userlandfs_read_stat(void *ns, void *node, struct stat *st); 55static int userlandfs_write_stat(void *ns, void *node, struct stat *st, 56 long mask); 57static int userlandfs_access(void *ns, void *node, int mode); 58 59// files 60static int userlandfs_create(void *ns, void *dir, const char *name, 61 int openMode, int mode, vnode_id *vnid, void **cookie); 62static int userlandfs_open(void *ns, void *node, int openMode, void **cookie); 63static int userlandfs_close(void *ns, void *node, void *cookie); 64static int userlandfs_free_cookie(void *ns, void *node, void *cookie); 65static int userlandfs_read(void *ns, void *node, void *cookie, off_t pos, 66 void *buffer, size_t *bufferSize); 67static int userlandfs_write(void *ns, void *node, void *cookie, off_t pos, 68 const void *buffer, size_t *bufferSize); 69static int userlandfs_ioctl(void *ns, void *node, void *cookie, int cmd, 70 void *buffer, size_t bufferSize); 71static int userlandfs_setflags(void *ns, void *node, void *cookie, int flags); 72static int userlandfs_select(void *ns, void *node, void *cookie, uint8 event, 73 uint32 ref, selectsync *sync); 74static int userlandfs_deselect(void *ns, void *node, void *cookie, uint8 event, 75 selectsync *sync); 76 77// hard links / symlinks 78static int userlandfs_link(void *ns, void *dir, const char *name, void *node); 79static int userlandfs_unlink(void *ns, void *dir, const char *name); 80static int userlandfs_symlink(void *ns, void *dir, const char *name, 81 const char *path); 82static int userlandfs_read_link(void *ns, void *node, char *buffer, 83 size_t *bufferSize); 84static int userlandfs_rename(void *ns, void *oldDir, const char *oldName, 85 void *newDir, const char *newName); 86 87// directories 88static int userlandfs_mkdir(void *ns, void *dir, const char *name, int mode); 89static int userlandfs_rmdir(void *ns, void *dir, const char *name); 90static int userlandfs_open_dir(void *ns, void *node, void **cookie); 91static int userlandfs_close_dir(void *ns, void *node, void *cookie); 92static int userlandfs_free_dir_cookie(void *ns, void *node, void *cookie); 93static int userlandfs_read_dir(void *ns, void *node, void *cookie, 94 long *count, struct dirent *buffer, size_t bufferSize); 95static int userlandfs_rewind_dir(void *ns, void *node, void *cookie); 96static int userlandfs_walk(void *ns, void *dir, const char *entryName, 97 char **resolvedPath, vnode_id *vnid); 98 99// attributes 100static int userlandfs_open_attrdir(void *ns, void *node, void **cookie); 101static int userlandfs_close_attrdir(void *ns, void *node, void *cookie); 102static int userlandfs_free_attrdir_cookie(void *ns, void *node, void *cookie); 103static int userlandfs_read_attrdir(void *ns, void *node, void *cookie, 104 long *count, struct dirent *buffer, size_t bufferSize); 105static int userlandfs_read_attr(void *ns, void *node, const char *name, 106 int type, void *buffer, size_t *bufferSize, off_t pos); 107static int userlandfs_rewind_attrdir(void *ns, void *node, void *cookie); 108static int userlandfs_write_attr(void *ns, void *node, const char *name, 109 int type, const void *buffer, size_t *bufferSize, off_t pos); 110static int userlandfs_remove_attr(void *ns, void *node, const char *name); 111static int userlandfs_rename_attr(void *ns, void *node, const char *oldName, 112 const char *newName); 113static int userlandfs_stat_attr(void *ns, void *node, const char *name, 114 struct attr_info *attrInfo); 115 116// indices 117static int userlandfs_open_indexdir(void *ns, void **cookie); 118static int userlandfs_close_indexdir(void *ns, void *cookie); 119static int userlandfs_free_indexdir_cookie(void *ns, void *node, void *cookie); 120static int userlandfs_read_indexdir(void *ns, void *cookie, long *count, 121 struct dirent *buffer, size_t bufferSize); 122static int userlandfs_rewind_indexdir(void *ns, void *cookie); 123static int userlandfs_create_index(void *ns, const char *name, int type, int flags); 124static int userlandfs_remove_index(void *ns, const char *name); 125static int userlandfs_rename_index(void *ns, const char *oldName, 126 const char *newName); 127static int userlandfs_stat_index(void *ns, const char *name, 128 struct index_info *indexInfo); 129 130// queries 131static int userlandfs_open_query(void *ns, const char *queryString, ulong flags, 132 port_id port, long token, void **cookie); 133static int userlandfs_close_query(void *ns, void *cookie); 134static int userlandfs_free_query_cookie(void *ns, void *node, void *cookie); 135static int userlandfs_read_query(void *ns, void *cookie, long *count, 136 struct dirent *buffer, size_t bufferSize); 137 138} // extern "C" 139 140/* vnode_ops struct. Fill this in to tell the kernel how to call 141 functions in your driver. 142*/ 143vnode_ops fs_entry = { 144 &userlandfs_read_vnode, // read_vnode 145 &userlandfs_write_vnode, // write_vnode 146 &userlandfs_remove_vnode, // remove_vnode 147 NULL, // secure_vnode (not needed) 148 &userlandfs_walk, // walk 149 &userlandfs_access, // access 150 &userlandfs_create, // create 151 &userlandfs_mkdir, // mkdir 152 &userlandfs_symlink, // symlink 153 &userlandfs_link, // link 154 &userlandfs_rename, // rename 155 &userlandfs_unlink, // unlink 156 &userlandfs_rmdir, // rmdir 157 &userlandfs_read_link, // readlink 158 &userlandfs_open_dir, // opendir 159 &userlandfs_close_dir, // closedir 160 &userlandfs_free_dir_cookie, // free_dircookie 161 &userlandfs_rewind_dir, // rewinddir 162 &userlandfs_read_dir, // readdir 163 &userlandfs_open, // open file 164 &userlandfs_close, // close file 165 &userlandfs_free_cookie, // free cookie 166 &userlandfs_read, // read file 167 &userlandfs_write, // write file 168 NULL, // readv 169 NULL, // writev 170 &userlandfs_ioctl, // ioctl 171 &userlandfs_setflags, // setflags file 172 &userlandfs_read_stat, // read stat 173 &userlandfs_write_stat, // write stat 174 &userlandfs_fsync, // fsync 175 &userlandfs_initialize, // initialize 176 &userlandfs_mount, // mount 177 &userlandfs_unmount, // unmount 178 &userlandfs_sync, // sync 179 &userlandfs_read_fs_stat, // read fs stat 180 &userlandfs_write_fs_stat, // write fs stat 181 &userlandfs_select, // select 182 &userlandfs_deselect, // deselect 183 184 &userlandfs_open_indexdir, // open index dir 185 &userlandfs_close_indexdir, // close index dir 186 &userlandfs_free_indexdir_cookie, // free index dir cookie 187 &userlandfs_rewind_indexdir, // rewind index dir 188 &userlandfs_read_indexdir, // read index dir 189 &userlandfs_create_index, // create index 190 &userlandfs_remove_index, // remove index 191 &userlandfs_rename_index, // rename index 192 &userlandfs_stat_index, // stat index 193 194 &userlandfs_open_attrdir, // open attr dir 195 &userlandfs_close_attrdir, // close attr dir 196 &userlandfs_free_attrdir_cookie, // free attr dir cookie 197 &userlandfs_rewind_attrdir, // rewind attr dir 198 &userlandfs_read_attrdir, // read attr dir 199 &userlandfs_write_attr, // write attr 200 &userlandfs_read_attr, // read attr 201 &userlandfs_remove_attr, // remove attr 202 &userlandfs_rename_attr, // rename attr 203 &userlandfs_stat_attr, // stat attr 204 205 &userlandfs_open_query, // open query 206 &userlandfs_close_query, // close query 207 &userlandfs_free_query_cookie, // free query cookie 208 &userlandfs_read_query, // read query 209}; 210 211int32 api_version = B_CUR_FS_API_VERSION; 212 213// #pragma mark - 214// #pragma mark ----- fs ----- 215 216// parse_parameters 217static 218status_t 219parse_parameters(const void *_parameters, int32 _len, String &fsName, 220 const char **fsParameters, int32 *fsParameterLength) 221{ 222 // check parameters 223 if (!_parameters || _len <= 0) 224 return B_BAD_VALUE; 225 const char* parameters = (const char*)_parameters; 226 int32 len = strnlen(parameters, _len); 227 // skip leading white space 228 for (; len > 0; parameters++, len--) { 229 if (*parameters != ' ' && *parameters != '\t' && *parameters != '\n') 230 break; 231 } 232 if (len == 0) 233 return B_BAD_VALUE; 234 // get the file system name 235 int32 fsNameLen = len; 236 for (int32 i = 0; i < len; i++) { 237 if (parameters[i] == ' ' || parameters[i] == '\t' 238 || parameters[i] == '\n') { 239 fsNameLen = i; 240 break; 241 } 242 } 243 fsName.SetTo(parameters, fsNameLen); 244 if (fsName.GetLength() == 0) { 245 exit_debugging(); 246 return B_NO_MEMORY; 247 } 248 parameters += fsNameLen; 249 len -= fsNameLen; 250 // skip leading white space of the FS parameters 251 for (; len > 0; parameters++, len--) { 252 if (*parameters != ' ' && *parameters != '\t' && *parameters != '\n') 253 break; 254 } 255 *fsParameters = parameters; 256 *fsParameterLength = len; 257 return B_OK; 258} 259 260// userlandfs_mount 261static 262int 263userlandfs_mount(nspace_id nsid, const char *device, ulong flags, 264 void *parameters, size_t len, void **data, vnode_id *rootID) 265{ 266 status_t error = B_OK; 267 init_debugging(); 268 // get the parameters 269 String fsName; 270 const char* fsParameters; 271 int32 fsParameterLength; 272 error = parse_parameters(parameters, len, fsName, &fsParameters, 273 &fsParameterLength); 274 if (error != B_OK) { 275 exit_debugging(); 276 return error; 277 } 278 // make sure there is a UserlandFS we can work with 279 UserlandFS* userlandFS = NULL; 280 error = UserlandFS::RegisterUserlandFS(&userlandFS); 281 if (error != B_OK) { 282 exit_debugging(); 283 return error; 284 } 285 // get the file system 286 FileSystem* fileSystem = NULL; 287 error = userlandFS->RegisterFileSystem(fsName.GetString(), &fileSystem); 288 if (error != B_OK) { 289 UserlandFS::UnregisterUserlandFS(); 290 exit_debugging(); 291 return error; 292 } 293 // mount the volume 294 Volume* volume = NULL; 295 error = fileSystem->Mount(nsid, device, flags, fsParameters, 296 fsParameterLength, &volume); 297 if (error != B_OK) { 298 userlandFS->UnregisterFileSystem(fileSystem); 299 UserlandFS::UnregisterUserlandFS(); 300 exit_debugging(); 301 return error; 302 } 303 *data = volume; 304 *rootID = volume->GetRootID(); 305 return error; 306} 307 308// userlandfs_unmount 309static 310int 311userlandfs_unmount(void *ns) 312{ 313 Volume* volume = (Volume*)ns; 314 FileSystem* fileSystem = volume->GetFileSystem(); 315 status_t error = volume->Unmount(); 316 // The error code the FS's unmount hook returns is completely irrelevant to 317 // the VFS. It considers the volume unmounted in any case. 318 volume->RemoveReference(); 319 UserlandFS::GetUserlandFS()->UnregisterFileSystem(fileSystem); 320 UserlandFS::UnregisterUserlandFS(); 321 exit_debugging(); 322 return error; 323} 324 325// userlandfs_initialize 326static 327int 328userlandfs_initialize(const char *deviceName, void *parameters, 329 size_t len) 330{ 331 init_debugging(); 332 // get the parameters 333 String fsName; 334 const char* fsParameters; 335 int32 fsParameterLength; 336 status_t error = parse_parameters(parameters, len, fsName, &fsParameters, 337 &fsParameterLength); 338 // make sure there is a UserlandFS we can work with 339 UserlandFS* userlandFS = NULL; 340 error = UserlandFS::RegisterUserlandFS(&userlandFS); 341 if (error != B_OK) { 342 exit_debugging(); 343 return error; 344 } 345 // get the file system 346 FileSystem* fileSystem = NULL; 347 if (error == B_OK) 348 error = userlandFS->RegisterFileSystem(fsName.GetString(), &fileSystem); 349 // initialize the volume 350 if (error == B_OK) { 351 error = fileSystem->Initialize(deviceName, fsParameters, 352 fsParameterLength); 353 } 354 // cleanup 355 if (fileSystem) 356 userlandFS->UnregisterFileSystem(fileSystem); 357 UserlandFS::UnregisterUserlandFS(); 358 exit_debugging(); 359 return error; 360} 361 362// userlandfs_sync 363static 364int 365userlandfs_sync(void *ns) 366{ 367 Volume* volume = (Volume*)ns; 368 PRINT(("userlandfs_sync(%p)\n", ns)); 369 status_t error = volume->Sync(); 370 PRINT(("userlandfs_sync() done: %lx \n", error)); 371 return error; 372} 373 374// userlandfs_read_fs_stat 375static 376int 377userlandfs_read_fs_stat(void *ns, struct fs_info *info) 378{ 379 Volume* volume = (Volume*)ns; 380 PRINT(("userlandfs_read_fs_stat(%p, %p)\n", ns, info)); 381 status_t error = volume->ReadFSStat(info); 382 PRINT(("userlandfs_read_fs_stat() done: %lx \n", error)); 383 return error; 384} 385 386// userlandfs_write_fs_stat 387static 388int 389userlandfs_write_fs_stat(void *ns, struct fs_info *info, long mask) 390{ 391 Volume* volume = (Volume*)ns; 392 PRINT(("userlandfs_write_fs_stat(%p, %p, %ld)\n", ns, info, mask)); 393 status_t error = volume->WriteFSStat(info, mask); 394 PRINT(("userlandfs_write_fs_stat() done: %lx \n", error)); 395 return error; 396} 397 398// #pragma mark - 399// #pragma mark ----- vnodes ----- 400 401// userlandfs_read_vnode 402static 403int 404userlandfs_read_vnode(void *ns, vnode_id vnid, char reenter, void **node) 405{ 406 Volume* volume = (Volume*)ns; 407 PRINT(("userlandfs_read_vnode(%p, %Ld, %d, %p)\n", ns, vnid, reenter, 408 node)); 409 status_t error = volume->ReadVNode(vnid, reenter, node); 410 PRINT(("userlandfs_read_vnode() done: (%lx, %p)\n", error, *node)); 411 return error; 412} 413 414// userlandfs_write_vnode 415static 416int 417userlandfs_write_vnode(void *ns, void *node, char reenter) 418{ 419 Volume* volume = (Volume*)ns; 420// DANGER: If dbg_printf() is used, this thread will enter another FS and 421// even perform a write operation. The is dangerous here, since this hook 422// may be called out of the other FSs, since, for instance a put_vnode() 423// called from another FS may cause the VFS layer to free vnodes and thus 424// invoke this hook. 425// PRINT(("userlandfs_write_vnode(%p, %p, %d)\n", ns, node, reenter)); 426 status_t error = volume->WriteVNode(node, reenter); 427// PRINT(("userlandfs_write_vnode() done: %lx\n", error)); 428 return error; 429} 430 431// userlandfs_remove_vnode 432static 433int 434userlandfs_remove_vnode(void *ns, void *node, char reenter) 435{ 436 Volume* volume = (Volume*)ns; 437// DANGER: See userlandfs_write_vnode(). 438// PRINT(("userlandfs_remove_vnode(%p, %p, %d)\n", ns, node, reenter)); 439 status_t error = volume->RemoveVNode(node, reenter); 440// PRINT(("userlandfs_remove_vnode() done: %lx\n", error)); 441 return error; 442} 443 444// #pragma mark - 445// #pragma mark ----- nodes ----- 446 447// userlandfs_fsync 448static 449int 450userlandfs_fsync(void *ns, void *node) 451{ 452 Volume* volume = (Volume*)ns; 453 PRINT(("userlandfs_fsync(%p, %p)\n", ns, node)); 454 status_t error = volume->FSync(node); 455 PRINT(("userlandfs_fsync() done: %lx\n", error)); 456 return error; 457} 458 459// userlandfs_read_stat 460static 461int 462userlandfs_read_stat(void *ns, void *node, struct stat *st) 463{ 464 Volume* volume = (Volume*)ns; 465 PRINT(("userlandfs_read_stat(%p, %p, %p)\n", ns, node, st)); 466 status_t error = volume->ReadStat(node, st); 467 PRINT(("userlandfs_read_stat() done: %lx\n", error)); 468 return error; 469} 470 471// userlandfs_write_stat 472static 473int 474userlandfs_write_stat(void *ns, void *node, struct stat *st, long mask) 475{ 476 Volume* volume = (Volume*)ns; 477 PRINT(("userlandfs_write_stat(%p, %p, %p, %ld)\n", ns, node, st, mask)); 478 status_t error = volume->WriteStat(node, st, mask); 479 PRINT(("userlandfs_write_stat() done: %lx\n", error)); 480 return error; 481} 482 483// userlandfs_access 484static 485int 486userlandfs_access(void *ns, void *node, int mode) 487{ 488 Volume* volume = (Volume*)ns; 489 PRINT(("userlandfs_access(%p, %p, %d)\n", ns, node, mode)); 490 status_t error = volume->Access(node, mode); 491 PRINT(("userlandfs_access() done: %lx\n", error)); 492 return error; 493} 494 495// #pragma mark - 496// #pragma mark ----- files ----- 497 498// userlandfs_create 499static 500int 501userlandfs_create(void *ns, void *dir, const char *name, int openMode, int mode, 502 vnode_id *vnid, void **cookie) 503{ 504 Volume* volume = (Volume*)ns; 505 PRINT(("userlandfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", ns, dir, 506 name, openMode, mode, vnid, cookie)); 507 status_t error = volume->Create(dir, name, openMode, mode, vnid, cookie); 508 PRINT(("userlandfs_create() done: (%lx, %Ld, %p)\n", error, *vnid, 509 *cookie)); 510 return error; 511} 512 513// userlandfs_open 514static 515int 516userlandfs_open(void *ns, void *node, int openMode, void **cookie) 517{ 518 Volume* volume = (Volume*)ns; 519 PRINT(("userlandfs_open(%p, %p, %d)\n", ns, node, openMode)); 520 status_t error = volume->Open(node, openMode, cookie); 521 PRINT(("userlandfs_open() done: (%lx, %p)\n", error, *cookie)); 522 return error; 523} 524 525// userlandfs_close 526static 527int 528userlandfs_close(void *ns, void *node, void *cookie) 529{ 530 Volume* volume = (Volume*)ns; 531 PRINT(("userlandfs_close(%p, %p, %p)\n", ns, node, cookie)); 532 status_t error = volume->Close(node, cookie); 533 PRINT(("userlandfs_close() done: %lx\n", error)); 534 return error; 535} 536 537// userlandfs_free_cookie 538static 539int 540userlandfs_free_cookie(void *ns, void *node, void *cookie) 541{ 542 Volume* volume = (Volume*)ns; 543 PRINT(("userlandfs_free_cookie(%p, %p, %p)\n", ns, node, cookie)); 544 status_t error = volume->FreeCookie(node, cookie); 545 PRINT(("userlandfs_free_cookie() done: %lx\n", error)); 546 return error; 547} 548 549// userlandfs_read 550static 551int 552userlandfs_read(void *ns, void *node, void *cookie, off_t pos, void *buffer, 553 size_t *bufferSize) 554{ 555 Volume* volume = (Volume*)ns; 556 PRINT(("userlandfs_read(%p, %p, %p, %Ld, %p, %lu)\n", ns, node, cookie, pos, 557 buffer, *bufferSize)); 558 status_t error = volume->Read(node, cookie, pos, buffer, *bufferSize, 559 bufferSize); 560 PRINT(("userlandfs_read() done: (%lx, %lu)\n", error, *bufferSize)); 561 return error; 562} 563 564// userlandfs_write 565static 566int 567userlandfs_write(void *ns, void *node, void *cookie, off_t pos, 568 const void *buffer, size_t *bufferSize) 569{ 570 Volume* volume = (Volume*)ns; 571 PRINT(("userlandfs_write(%p, %p, %p, %Ld, %p, %lu)\n", ns, node, cookie, pos, 572 buffer, *bufferSize)); 573 status_t error = volume->Write(node, cookie, pos, buffer, *bufferSize, 574 bufferSize); 575 PRINT(("userlandfs_write() done: (%lx, %lu)\n", error, *bufferSize)); 576 return error; 577} 578 579// userlandfs_ioctl 580static 581int 582userlandfs_ioctl(void *ns, void *node, void *cookie, int cmd, void *buffer, 583 size_t bufferSize) 584{ 585 Volume* volume = (Volume*)ns; 586 PRINT(("userlandfs_ioctl(%p, %p, %p, %d, %p, %lu)\n", ns, node, cookie, cmd, 587 buffer, bufferSize)); 588 status_t error = volume->IOCtl(node, cookie, cmd, buffer, bufferSize); 589 PRINT(("userlandfs_ioctl() done: (%lx)\n", error)); 590 return error; 591} 592 593// userlandfs_setflags 594static 595int 596userlandfs_setflags(void *ns, void *node, void *cookie, int flags) 597{ 598 Volume* volume = (Volume*)ns; 599 PRINT(("userlandfs_setflags(%p, %p, %p, %d)\n", ns, node, cookie, flags)); 600 status_t error = volume->SetFlags(node, cookie, flags); 601 PRINT(("userlandfs_setflags() done: (%lx)\n", error)); 602 return error; 603} 604 605// userlandfs_select 606static 607int 608userlandfs_select(void *ns, void *node, void *cookie, uint8 event, uint32 ref, 609 selectsync *sync) 610{ 611 Volume* volume = (Volume*)ns; 612 PRINT(("userlandfs_select(%p, %p, %p, %hhd, %lu, %p)\n", ns, node, cookie, 613 event, ref, sync)); 614 status_t error = volume->Select(node, cookie, event, ref, sync); 615 PRINT(("userlandfs_select() done: (%lx)\n", error)); 616 return error; 617} 618 619// userlandfs_deselect 620static 621int 622userlandfs_deselect(void *ns, void *node, void *cookie, uint8 event, 623 selectsync *sync) 624{ 625 Volume* volume = (Volume*)ns; 626 PRINT(("userlandfs_deselect(%p, %p, %p, %hhd, %p)\n", ns, node, cookie, 627 event, sync)); 628 status_t error = volume->Deselect(node, cookie, event, sync); 629 PRINT(("userlandfs_deselect() done: (%lx)\n", error)); 630 return error; 631} 632 633// #pragma mark - 634// #pragma mark ----- hard links / symlinks ----- 635 636// userlandfs_link 637static 638int 639userlandfs_link(void *ns, void *dir, const char *name, void *node) 640{ 641 Volume* volume = (Volume*)ns; 642 PRINT(("userlandfs_link(%p, %p, `%s', %p)\n", ns, dir, name, node)); 643 status_t error = volume->Link(dir, name, node); 644 PRINT(("userlandfs_link() done: (%lx)\n", error)); 645 return error; 646} 647 648// userlandfs_unlink 649static 650int 651userlandfs_unlink(void *ns, void *dir, const char *name) 652{ 653 Volume* volume = (Volume*)ns; 654 PRINT(("userlandfs_unlink(%p, %p, `%s')\n", ns, dir, name)); 655 status_t error = volume->Unlink(dir, name); 656 PRINT(("userlandfs_unlink() done: (%lx)\n", error)); 657 return error; 658} 659 660// userlandfs_symlink 661static 662int 663userlandfs_symlink(void *ns, void *dir, const char *name, const char *path) 664{ 665 Volume* volume = (Volume*)ns; 666 PRINT(("userlandfs_symlink(%p, %p, `%s', `%s')\n", ns, dir, name, path)); 667 status_t error = volume->Symlink(dir, name, path); 668 PRINT(("userlandfs_symlink() done: (%lx)\n", error)); 669 return error; 670} 671 672// userlandfs_read_link 673static 674int 675userlandfs_read_link(void *ns, void *node, char *buffer, size_t *bufferSize) 676{ 677 Volume* volume = (Volume*)ns; 678 PRINT(("userlandfs_read_link(%p, %p, %p, %lu)\n", ns, node, buffer, 679 *bufferSize)); 680 status_t error = volume->ReadLink(node, buffer, *bufferSize, bufferSize); 681 PRINT(("userlandfs_read_link() done: (%lx, %lu)\n", error, *bufferSize)); 682 return error; 683} 684 685// userlandfs_rename 686static 687int 688userlandfs_rename(void *ns, void *oldDir, const char *oldName, void *newDir, 689 const char *newName) 690{ 691 Volume* volume = (Volume*)ns; 692 PRINT(("userlandfs_rename(%p, %p, `%s', %p, `%s')\n", ns, oldDir, oldName, 693 newDir, newName)); 694 status_t error = volume->Rename(oldDir, oldName, newDir, newName); 695 PRINT(("userlandfs_rename() done: (%lx)\n", error)); 696 return error; 697} 698 699// #pragma mark - 700// #pragma mark ----- directories ----- 701 702// userlandfs_mkdir 703static 704int 705userlandfs_mkdir(void *ns, void *dir, const char *name, int mode) 706{ 707 Volume* volume = (Volume*)ns; 708 PRINT(("userlandfs_mkdir(%p, %p, `%s', %d)\n", ns, dir, name, mode)); 709 status_t error = volume->MkDir(dir, name, mode); 710 PRINT(("userlandfs_mkdir() done: (%lx)\n", error)); 711 return error; 712} 713 714// userlandfs_rmdir 715static 716int 717userlandfs_rmdir(void *ns, void *dir, const char *name) 718{ 719 Volume* volume = (Volume*)ns; 720 PRINT(("userlandfs_rmdir(%p, %p, `%s')\n", ns, dir, name)); 721 status_t error = volume->RmDir(dir, name); 722 PRINT(("userlandfs_rmdir() done: (%lx)\n", error)); 723 return error; 724} 725 726// userlandfs_open_dir 727static 728int 729userlandfs_open_dir(void *ns, void *node, void **cookie) 730{ 731 Volume* volume = (Volume*)ns; 732 PRINT(("userlandfs_open_dir(%p, %p)\n", ns, node)); 733 status_t error = volume->OpenDir(node, cookie); 734 PRINT(("userlandfs_open_dir() done: (%lx, %p)\n", error, *cookie)); 735 return error; 736} 737 738// userlandfs_close_dir 739static 740int 741userlandfs_close_dir(void *ns, void *node, void *cookie) 742{ 743 Volume* volume = (Volume*)ns; 744 PRINT(("userlandfs_close_dir(%p, %p, %p)\n", ns, node, cookie)); 745 status_t error = volume->CloseDir(node, cookie); 746 PRINT(("userlandfs_close_dir() done: %lx\n", error)); 747 return error; 748} 749 750// userlandfs_free_dir_cookie 751static 752int 753userlandfs_free_dir_cookie(void *ns, void *node, void *cookie) 754{ 755 Volume* volume = (Volume*)ns; 756 PRINT(("userlandfs_free_dir_cookie(%p, %p, %p)\n", ns, node, cookie)); 757 status_t error = volume->FreeDirCookie(node, cookie); 758 PRINT(("userlandfs_free_dir_cookie() done: %lx \n", error)); 759 return error; 760} 761 762// userlandfs_read_dir 763static 764int 765userlandfs_read_dir(void *ns, void *node, void *cookie, long *count, 766 struct dirent *buffer, size_t bufferSize) 767{ 768 Volume* volume = (Volume*)ns; 769 PRINT(("userlandfs_read_dir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, cookie, 770 *count, buffer, bufferSize)); 771 status_t error = volume->ReadDir(node, cookie, buffer, bufferSize, *count, 772 count); 773 PRINT(("userlandfs_read_dir() done: (%lx, %ld)\n", error, *count)); 774 #if DEBUG 775 dirent* entry = buffer; 776 for (int32 i = 0; i < *count; i++) { 777 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 778 // we need to work around. 779 char name[B_FILE_NAME_LENGTH]; 780 int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1); 781 strncpy(name, entry->d_name, nameLen); 782 name[nameLen] = '\0'; 783 PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " 784 "d_reclen: %hu, d_name: `%s'\n", 785 entry->d_dev, entry->d_pdev, entry->d_ino, entry->d_pino, 786 entry->d_reclen, name)); 787 entry = (dirent*)((char*)entry + entry->d_reclen); 788 } 789 #endif 790 return error; 791} 792 793// userlandfs_rewind_dir 794static 795int 796userlandfs_rewind_dir(void *ns, void *node, void *cookie) 797{ 798 Volume* volume = (Volume*)ns; 799 PRINT(("userlandfs_rewind_dir(%p, %p, %p)\n", ns, node, cookie)); 800 status_t error = volume->RewindDir(node, cookie); 801 PRINT(("userlandfs_rewind_dir() done: %lx\n", error)); 802 return error; 803} 804 805// userlandfs_walk 806static 807int 808userlandfs_walk(void *ns, void *dir, const char *entryName, 809 char **resolvedPath, vnode_id *vnid) 810{ 811 Volume* volume = (Volume*)ns; 812 PRINT(("userlandfs_walk(%p, %p, `%s', %p, %p)\n", ns, dir, 813 entryName, resolvedPath, vnid)); 814 status_t error = volume->Walk(dir, entryName, resolvedPath, vnid); 815 PRINT(("userlandfs_walk() done: (%lx, `%s', %Ld)\n", error, 816 (resolvedPath ? *resolvedPath : NULL), *vnid)); 817 return error; 818} 819 820// #pragma mark - 821// #pragma mark ----- attributes ----- 822 823// userlandfs_open_attrdir 824static 825int 826userlandfs_open_attrdir(void *ns, void *node, void **cookie) 827{ 828 Volume* volume = (Volume*)ns; 829 PRINT(("userlandfs_open_attrdir(%p, %p)\n", ns, node)); 830 status_t error = volume->OpenAttrDir(node, cookie); 831 PRINT(("userlandfs_open_attrdir() done: (%lx, %p)\n", error, *cookie)); 832 return error; 833} 834 835// userlandfs_close_attrdir 836static 837int 838userlandfs_close_attrdir(void *ns, void *node, void *cookie) 839{ 840 Volume* volume = (Volume*)ns; 841 PRINT(("userlandfs_close_attrdir(%p, %p, %p)\n", ns, node, cookie)); 842 status_t error = volume->CloseAttrDir(node, cookie); 843 PRINT(("userlandfs_close_attrdir() done: (%lx)\n", error)); 844 return error; 845} 846 847// userlandfs_free_attrdir_cookie 848static 849int 850userlandfs_free_attrdir_cookie(void *ns, void *node, void *cookie) 851{ 852 Volume* volume = (Volume*)ns; 853 PRINT(("userlandfs_free_attrdir_cookie(%p, %p, %p)\n", ns, node, cookie)); 854 status_t error = volume->FreeAttrDirCookie(node, cookie); 855 PRINT(("userlandfs_free_attrdir_cookie() done: (%lx)\n", error)); 856 return error; 857} 858 859// userlandfs_read_attrdir 860static 861int 862userlandfs_read_attrdir(void *ns, void *node, void *cookie, long *count, 863 struct dirent *buffer, size_t bufferSize) 864{ 865 Volume* volume = (Volume*)ns; 866 PRINT(("userlandfs_read_attrdir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, 867 cookie, *count, buffer, bufferSize)); 868 status_t error = volume->ReadAttrDir(node, cookie, buffer, bufferSize, 869 *count, count); 870 PRINT(("userlandfs_read_attrdir() done: (%lx, %ld)\n", error, *count)); 871 return error; 872} 873 874// userlandfs_rewind_attrdir 875static 876int 877userlandfs_rewind_attrdir(void *ns, void *node, void *cookie) 878{ 879 Volume* volume = (Volume*)ns; 880 PRINT(("userlandfs_rewind_attrdir(%p, %p, %p)\n", ns, node, cookie)); 881 status_t error = volume->RewindAttrDir(node, cookie); 882 PRINT(("userlandfs_rewind_attrdir() done: (%lx)\n", error)); 883 return error; 884} 885 886// userlandfs_read_attr 887static 888int 889userlandfs_read_attr(void *ns, void *node, const char *name, int type, 890 void *buffer, size_t *bufferSize, off_t pos) 891{ 892 Volume* volume = (Volume*)ns; 893 PRINT(("userlandfs_read_attr(%p, %p, `%s', %d, %p, %lu, %Ld)\n", ns, node, 894 name, type, buffer, *bufferSize, pos)); 895 status_t error = volume->ReadAttr(node, name, type, pos, buffer, 896 *bufferSize, bufferSize); 897 PRINT(("userlandfs_read_attr() done: (%lx, %ld)\n", error, *bufferSize)); 898 return error; 899} 900 901// userlandfs_write_attr 902static 903int 904userlandfs_write_attr(void *ns, void *node, const char *name, int type, 905 const void *buffer, size_t *bufferSize, off_t pos) 906{ 907 Volume* volume = (Volume*)ns; 908 PRINT(("userlandfs_write_attr(%p, %p, `%s', %d, %p, %lu, %Ld)\n", ns, node, 909 name, type, buffer, *bufferSize, pos)); 910 status_t error = volume->WriteAttr(node, name, type, pos, buffer, 911 *bufferSize, bufferSize); 912 PRINT(("userlandfs_write_attr() done: (%lx, %ld)\n", error, *bufferSize)); 913 return error; 914} 915 916// userlandfs_remove_attr 917static 918int 919userlandfs_remove_attr(void *ns, void *node, const char *name) 920{ 921 Volume* volume = (Volume*)ns; 922 PRINT(("userlandfs_remove_attr(%p, %p, `%s')\n", ns, node, name)); 923 status_t error = volume->RemoveAttr(node, name); 924 PRINT(("userlandfs_remove_attr() done: (%lx)\n", error)); 925 return error; 926} 927 928// userlandfs_rename_attr 929static 930int 931userlandfs_rename_attr(void *ns, void *node, const char *oldName, 932 const char *newName) 933{ 934 Volume* volume = (Volume*)ns; 935 PRINT(("userlandfs_rename_attr(%p, %p, `%s', `%s')\n", ns, node, oldName, 936 newName)); 937 status_t error = volume->RenameAttr(node, oldName, newName); 938 PRINT(("userlandfs_rename_attr() done: (%lx)\n", error)); 939 return error; 940} 941 942// userlandfs_stat_attr 943static 944int 945userlandfs_stat_attr(void *ns, void *node, const char *name, 946 struct attr_info *attrInfo) 947{ 948 Volume* volume = (Volume*)ns; 949 PRINT(("userlandfs_stat_attr(%p, %p, `%s', %p)\n", ns, node, name, 950 attrInfo)); 951 status_t error = volume->StatAttr(node, name, attrInfo); 952 PRINT(("userlandfs_stat_attr() done: (%lx)\n", error)); 953 return error; 954} 955 956// #pragma mark - 957// #pragma mark ----- indices ----- 958 959// userlandfs_open_indexdir 960static 961int 962userlandfs_open_indexdir(void *ns, void **cookie) 963{ 964 Volume* volume = (Volume*)ns; 965 PRINT(("userlandfs_open_indexdir(%p, %p)\n", ns, cookie)); 966 status_t error = volume->OpenIndexDir(cookie); 967 PRINT(("userlandfs_open_indexdir() done: (%lx, %p)\n", error, *cookie)); 968 return error; 969} 970 971// userlandfs_close_indexdir 972static 973int 974userlandfs_close_indexdir(void *ns, void *cookie) 975{ 976 Volume* volume = (Volume*)ns; 977 PRINT(("userlandfs_close_indexdir(%p, %p)\n", ns, cookie)); 978 status_t error = volume->CloseIndexDir(cookie); 979 PRINT(("userlandfs_close_indexdir() done: (%lx)\n", error)); 980 return error; 981} 982 983// userlandfs_free_indexdir_cookie 984static 985int 986userlandfs_free_indexdir_cookie(void *ns, void *node, void *cookie) 987{ 988 Volume* volume = (Volume*)ns; 989 PRINT(("userlandfs_free_indexdir_cookie(%p, %p)\n", ns, cookie)); 990 status_t error = volume->FreeIndexDirCookie(cookie); 991 PRINT(("userlandfs_free_indexdir_cookie() done: (%lx)\n", error)); 992 return error; 993} 994 995// userlandfs_read_indexdir 996static 997int 998userlandfs_read_indexdir(void *ns, void *cookie, long *count, 999 struct dirent *buffer, size_t bufferSize) 1000{ 1001 Volume* volume = (Volume*)ns; 1002 PRINT(("userlandfs_read_indexdir(%p, %p, %ld, %p, %lu)\n", ns, cookie, 1003 *count, buffer, bufferSize)); 1004 status_t error = volume->ReadIndexDir(cookie, buffer, bufferSize, 1005 *count, count); 1006 PRINT(("userlandfs_read_indexdir() done: (%lx, %ld)\n", error, *count)); 1007 return error; 1008} 1009 1010// userlandfs_rewind_indexdir 1011static 1012int 1013userlandfs_rewind_indexdir(void *ns, void *cookie) 1014{ 1015 Volume* volume = (Volume*)ns; 1016 PRINT(("userlandfs_rewind_indexdir(%p, %p)\n", ns, cookie)); 1017 status_t error = volume->RewindIndexDir(cookie); 1018 PRINT(("userlandfs_rewind_indexdir() done: (%lx)\n", error)); 1019 return error; 1020} 1021 1022// userlandfs_create_index 1023static 1024int 1025userlandfs_create_index(void *ns, const char *name, int type, int flags) 1026{ 1027 Volume* volume = (Volume*)ns; 1028 PRINT(("userlandfs_create_index(%p, `%s', %d, %d)\n", ns, name, type, 1029 flags)); 1030 status_t error = volume->CreateIndex(name, type, flags); 1031 PRINT(("userlandfs_create_index() done: (%lx)\n", error)); 1032 return error; 1033} 1034 1035// userlandfs_remove_index 1036static 1037int 1038userlandfs_remove_index(void *ns, const char *name) 1039{ 1040 Volume* volume = (Volume*)ns; 1041 PRINT(("userlandfs_remove_index(%p, `%s')\n", ns, name)); 1042 status_t error = volume->RemoveIndex(name); 1043 PRINT(("userlandfs_remove_index() done: (%lx)\n", error)); 1044 return error; 1045} 1046 1047// userlandfs_rename_index 1048static 1049int 1050userlandfs_rename_index(void *ns, const char *oldName, const char *newName) 1051{ 1052 Volume* volume = (Volume*)ns; 1053 PRINT(("userlandfs_rename_index(%p, `%s', `%s')\n", ns, oldName, newName)); 1054 status_t error = volume->RenameIndex(oldName, newName); 1055 PRINT(("userlandfs_rename_index() done: (%lx)\n", error)); 1056 return error; 1057} 1058 1059// userlandfs_stat_index 1060static 1061int 1062userlandfs_stat_index(void *ns, const char *name, struct index_info *indexInfo) 1063{ 1064 Volume* volume = (Volume*)ns; 1065 PRINT(("userlandfs_stat_index(%p, `%s', %p)\n", ns, name, indexInfo)); 1066 status_t error = volume->StatIndex(name, indexInfo); 1067 PRINT(("userlandfs_stat_index() done: (%lx)\n", error)); 1068 return error; 1069} 1070 1071// #pragma mark - 1072// #pragma mark ----- queries ----- 1073 1074// userlandfs_open_query 1075static 1076int 1077userlandfs_open_query(void *ns, const char *queryString, ulong flags, 1078 port_id port, long token, void **cookie) 1079{ 1080 Volume* volume = (Volume*)ns; 1081 PRINT(("userlandfs_open_query(%p, `%s', %lu, %ld, %ld, %p)\n", ns, 1082 queryString, flags, port, token, cookie)); 1083 status_t error = volume->OpenQuery(queryString, flags, port, token, cookie); 1084 PRINT(("userlandfs_open_query() done: (%lx, %p)\n", error, *cookie)); 1085 return error; 1086} 1087 1088// userlandfs_close_query 1089static 1090int 1091userlandfs_close_query(void *ns, void *cookie) 1092{ 1093 Volume* volume = (Volume*)ns; 1094 PRINT(("userlandfs_close_query(%p, %p)\n", ns, cookie)); 1095 status_t error = volume->CloseQuery(cookie); 1096 PRINT(("userlandfs_close_query() done: (%lx)\n", error)); 1097 return error; 1098} 1099 1100// userlandfs_free_query_cookie 1101static 1102int 1103userlandfs_free_query_cookie(void *ns, void *node, void *cookie) 1104{ 1105 Volume* volume = (Volume*)ns; 1106 PRINT(("userlandfs_free_query_cookie(%p, %p)\n", ns, cookie)); 1107 status_t error = volume->FreeQueryCookie(cookie); 1108 PRINT(("userlandfs_free_query_cookie() done: (%lx)\n", error)); 1109 return error; 1110} 1111 1112// userlandfs_read_query 1113static 1114int 1115userlandfs_read_query(void *ns, void *cookie, long *count, 1116 struct dirent *buffer, size_t bufferSize) 1117{ 1118 Volume* volume = (Volume*)ns; 1119 PRINT(("userlandfs_read_query(%p, %p, %ld, %p, %lu)\n", ns, cookie, 1120 *count, buffer, bufferSize)); 1121 status_t error = volume->ReadQuery(cookie, buffer, bufferSize, 1122 *count, count); 1123 PRINT(("userlandfs_read_query() done: (%lx, %ld)\n", error, *count)); 1124 #if DEBUG 1125 if (*count > 0) { 1126 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so 1127 // we need to work around. 1128 char name[B_FILE_NAME_LENGTH]; 1129 int nameLen = strnlen(buffer->d_name, B_FILE_NAME_LENGTH - 1); 1130 strncpy(name, buffer->d_name, nameLen); 1131 name[nameLen] = '\0'; 1132 PRINT((" entry: d_dev: %ld, d_pdev: %ld, d_ino: %Ld, d_pino: %Ld, " 1133 "d_reclen: %hu, d_name: `%s'\n", 1134 buffer->d_dev, buffer->d_pdev, buffer->d_ino, buffer->d_pino, 1135 buffer->d_reclen, name)); 1136 } 1137 #endif 1138 return error; 1139} 1140 1141