1 /* 2 FUSE: Filesystem in Userspace 3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> 4 5 This program can be distributed under the terms of the GNU LGPLv2. 6 See the file COPYING.LIB. 7 */ 8 9 #ifndef _FUSE_LOWLEVEL_H_ 10 #define _FUSE_LOWLEVEL_H_ 11 12 /** @file 13 * 14 * Low level API 15 */ 16 17 #include "fuse_common.h" 18 19 #include <utime.h> 20 #include <fcntl.h> 21 #include <sys/types.h> 22 #include <sys/stat.h> 23 #include <sys/statvfs.h> 24 #include <sys/uio.h> 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 /* ----------------------------------------------------------- * 31 * Miscellaneous definitions * 32 * ----------------------------------------------------------- */ 33 34 /** The node ID of the root inode */ 35 #define FUSE_ROOT_ID 1 36 37 /** Inode number type */ 38 typedef unsigned long fuse_ino_t; 39 40 /** Request pointer type */ 41 typedef struct fuse_req *fuse_req_t; 42 43 /** 44 * Session 45 * 46 * This provides hooks for processing requests, and exiting 47 */ 48 struct fuse_session; 49 50 /** 51 * Channel 52 * 53 * A communication channel, providing hooks for sending and receiving 54 * messages 55 */ 56 struct fuse_chan; 57 58 /** Directory entry parameters supplied to fuse_reply_entry() */ 59 struct fuse_entry_param { 60 /** Unique inode number 61 * 62 * In lookup, zero means negative entry (from version 2.5) 63 * Returning ENOENT also means negative entry, but by setting zero 64 * ino the kernel may cache negative entries for entry_timeout 65 * seconds. 66 */ 67 fuse_ino_t ino; 68 69 /** Generation number for this entry. 70 * 71 * The ino/generation pair should be unique for the filesystem's 72 * lifetime. It must be non-zero, otherwise FUSE will treat it as an 73 * error. 74 */ 75 unsigned long generation; 76 77 /** Inode attributes. 78 * 79 * Even if attr_timeout == 0, attr must be correct. For example, 80 * for open(), FUSE uses attr.st_size from lookup() to determine 81 * how many bytes to request. If this value is not correct, 82 * incorrect data will be returned. 83 */ 84 struct stat attr; 85 86 /** Validity timeout (in seconds) for the attributes */ 87 double attr_timeout; 88 89 /** Validity timeout (in seconds) for the name */ 90 double entry_timeout; 91 }; 92 93 /** Additional context associated with requests */ 94 struct fuse_ctx { 95 /** User ID of the calling process */ 96 uid_t uid; 97 98 /** Group ID of the calling process */ 99 gid_t gid; 100 101 /** Thread ID of the calling process */ 102 pid_t pid; 103 104 /** Umask of the calling process (introduced in version 2.8) */ 105 mode_t umask; 106 }; 107 108 /* 'to_set' flags in setattr */ 109 #define FUSE_SET_ATTR_MODE (1 << 0) 110 #define FUSE_SET_ATTR_UID (1 << 1) 111 #define FUSE_SET_ATTR_GID (1 << 2) 112 #define FUSE_SET_ATTR_SIZE (1 << 3) 113 #define FUSE_SET_ATTR_ATIME (1 << 4) 114 #define FUSE_SET_ATTR_MTIME (1 << 5) 115 #define FUSE_SET_ATTR_ATIME_NOW (1 << 7) 116 #define FUSE_SET_ATTR_MTIME_NOW (1 << 8) 117 118 /* ----------------------------------------------------------- * 119 * Request methods and replies * 120 * ----------------------------------------------------------- */ 121 122 /** 123 * Low level filesystem operations 124 * 125 * Most of the methods (with the exception of init and destroy) 126 * receive a request handle (fuse_req_t) as their first argument. 127 * This handle must be passed to one of the specified reply functions. 128 * 129 * This may be done inside the method invocation, or after the call 130 * has returned. The request handle is valid until one of the reply 131 * functions is called. 132 * 133 * Other pointer arguments (name, fuse_file_info, etc) are not valid 134 * after the call has returned, so if they are needed later, their 135 * contents have to be copied. 136 * 137 * The filesystem sometimes needs to handle a return value of -ENOENT 138 * from the reply function, which means, that the request was 139 * interrupted, and the reply discarded. For example if 140 * fuse_reply_open() return -ENOENT means, that the release method for 141 * this file will not be called. 142 */ 143 struct fuse_lowlevel_ops { 144 /** 145 * Initialize filesystem 146 * 147 * Called before any other filesystem method 148 * 149 * There's no reply to this function 150 * 151 * @param userdata the user data passed to fuse_lowlevel_new() 152 */ 153 void (*init) (void *userdata, struct fuse_conn_info *conn); 154 155 /** 156 * Clean up filesystem 157 * 158 * Called on filesystem exit 159 * 160 * There's no reply to this function 161 * 162 * @param userdata the user data passed to fuse_lowlevel_new() 163 */ 164 void (*destroy) (void *userdata); 165 166 /** 167 * Look up a directory entry by name and get its attributes. 168 * 169 * Valid replies: 170 * fuse_reply_entry 171 * fuse_reply_err 172 * 173 * @param req request handle 174 * @param parent inode number of the parent directory 175 * @param name the name to look up 176 */ 177 void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name); 178 179 /** 180 * Forget about an inode 181 * 182 * The nlookup parameter indicates the number of lookups 183 * previously performed on this inode. 184 * 185 * If the filesystem implements inode lifetimes, it is recommended 186 * that inodes acquire a single reference on each lookup, and lose 187 * nlookup references on each forget. 188 * 189 * The filesystem may ignore forget calls, if the inodes don't 190 * need to have a limited lifetime. 191 * 192 * On unmount it is not guaranteed, that all referenced inodes 193 * will receive a forget message. 194 * 195 * Valid replies: 196 * fuse_reply_none 197 * 198 * @param req request handle 199 * @param ino the inode number 200 * @param nlookup the number of lookups to forget 201 */ 202 void (*forget) (fuse_req_t req, fuse_ino_t ino, unsigned long nlookup); 203 204 /** 205 * Get file attributes 206 * 207 * Valid replies: 208 * fuse_reply_attr 209 * fuse_reply_err 210 * 211 * @param req request handle 212 * @param ino the inode number 213 * @param fi for future use, currently always NULL 214 */ 215 void (*getattr) (fuse_req_t req, fuse_ino_t ino, 216 struct fuse_file_info *fi); 217 218 /** 219 * Set file attributes 220 * 221 * In the 'attr' argument only members indicated by the 'to_set' 222 * bitmask contain valid values. Other members contain undefined 223 * values. 224 * 225 * If the setattr was invoked from the ftruncate() system call 226 * under Linux kernel versions 2.6.15 or later, the fi->fh will 227 * contain the value set by the open method or will be undefined 228 * if the open method didn't set any value. Otherwise (not 229 * ftruncate call, or kernel version earlier than 2.6.15) the fi 230 * parameter will be NULL. 231 * 232 * Valid replies: 233 * fuse_reply_attr 234 * fuse_reply_err 235 * 236 * @param req request handle 237 * @param ino the inode number 238 * @param attr the attributes 239 * @param to_set bit mask of attributes which should be set 240 * @param fi file information, or NULL 241 * 242 * Changed in version 2.5: 243 * file information filled in for ftruncate 244 */ 245 void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr, 246 int to_set, struct fuse_file_info *fi); 247 248 /** 249 * Read symbolic link 250 * 251 * Valid replies: 252 * fuse_reply_readlink 253 * fuse_reply_err 254 * 255 * @param req request handle 256 * @param ino the inode number 257 */ 258 void (*readlink) (fuse_req_t req, fuse_ino_t ino); 259 260 /** 261 * Create file node 262 * 263 * Create a regular file, character device, block device, fifo or 264 * socket node. 265 * 266 * Valid replies: 267 * fuse_reply_entry 268 * fuse_reply_err 269 * 270 * @param req request handle 271 * @param parent inode number of the parent directory 272 * @param name to create 273 * @param mode file type and mode with which to create the new file 274 * @param rdev the device number (only valid if created file is a device) 275 */ 276 void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name, 277 mode_t mode, dev_t rdev); 278 279 /** 280 * Create a directory 281 * 282 * Valid replies: 283 * fuse_reply_entry 284 * fuse_reply_err 285 * 286 * @param req request handle 287 * @param parent inode number of the parent directory 288 * @param name to create 289 * @param mode with which to create the new file 290 */ 291 void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name, 292 mode_t mode); 293 294 /** 295 * Remove a file 296 * 297 * Valid replies: 298 * fuse_reply_err 299 * 300 * @param req request handle 301 * @param parent inode number of the parent directory 302 * @param name to remove 303 */ 304 void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name); 305 306 /** 307 * Remove a directory 308 * 309 * Valid replies: 310 * fuse_reply_err 311 * 312 * @param req request handle 313 * @param parent inode number of the parent directory 314 * @param name to remove 315 */ 316 void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name); 317 318 /** 319 * Create a symbolic link 320 * 321 * Valid replies: 322 * fuse_reply_entry 323 * fuse_reply_err 324 * 325 * @param req request handle 326 * @param link the contents of the symbolic link 327 * @param parent inode number of the parent directory 328 * @param name to create 329 */ 330 void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent, 331 const char *name); 332 333 /** Rename a file 334 * 335 * Valid replies: 336 * fuse_reply_err 337 * 338 * @param req request handle 339 * @param parent inode number of the old parent directory 340 * @param name old name 341 * @param newparent inode number of the new parent directory 342 * @param newname new name 343 */ 344 void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name, 345 fuse_ino_t newparent, const char *newname); 346 347 /** 348 * Create a hard link 349 * 350 * Valid replies: 351 * fuse_reply_entry 352 * fuse_reply_err 353 * 354 * @param req request handle 355 * @param ino the old inode number 356 * @param newparent inode number of the new parent directory 357 * @param newname new name to create 358 */ 359 void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, 360 const char *newname); 361 362 /** 363 * Open a file 364 * 365 * Open flags (with the exception of O_CREAT, O_EXCL, O_NOCTTY and 366 * O_TRUNC) are available in fi->flags. 367 * 368 * Filesystem may store an arbitrary file handle (pointer, index, 369 * etc) in fi->fh, and use this in other all other file operations 370 * (read, write, flush, release, fsync). 371 * 372 * Filesystem may also implement stateless file I/O and not store 373 * anything in fi->fh. 374 * 375 * There are also some flags (direct_io, keep_cache) which the 376 * filesystem may set in fi, to change the way the file is opened. 377 * See fuse_file_info structure in <fuse_common.h> for more details. 378 * 379 * Valid replies: 380 * fuse_reply_open 381 * fuse_reply_err 382 * 383 * @param req request handle 384 * @param ino the inode number 385 * @param fi file information 386 */ 387 void (*open) (fuse_req_t req, fuse_ino_t ino, 388 struct fuse_file_info *fi); 389 390 /** 391 * Read data 392 * 393 * Read should send exactly the number of bytes requested except 394 * on EOF or error, otherwise the rest of the data will be 395 * substituted with zeroes. An exception to this is when the file 396 * has been opened in 'direct_io' mode, in which case the return 397 * value of the read system call will reflect the return value of 398 * this operation. 399 * 400 * fi->fh will contain the value set by the open method, or will 401 * be undefined if the open method didn't set any value. 402 * 403 * Valid replies: 404 * fuse_reply_buf 405 * fuse_reply_err 406 * 407 * @param req request handle 408 * @param ino the inode number 409 * @param size number of bytes to read 410 * @param off offset to read from 411 * @param fi file information 412 */ 413 void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, 414 struct fuse_file_info *fi); 415 416 /** 417 * Write data 418 * 419 * Write should return exactly the number of bytes requested 420 * except on error. An exception to this is when the file has 421 * been opened in 'direct_io' mode, in which case the return value 422 * of the write system call will reflect the return value of this 423 * operation. 424 * 425 * fi->fh will contain the value set by the open method, or will 426 * be undefined if the open method didn't set any value. 427 * 428 * Valid replies: 429 * fuse_reply_write 430 * fuse_reply_err 431 * 432 * @param req request handle 433 * @param ino the inode number 434 * @param buf data to write 435 * @param size number of bytes to write 436 * @param off offset to write to 437 * @param fi file information 438 */ 439 void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf, 440 size_t size, off_t off, struct fuse_file_info *fi); 441 442 /** 443 * Flush method 444 * 445 * This is called on each close() of the opened file. 446 * 447 * Since file descriptors can be duplicated (dup, dup2, fork), for 448 * one open call there may be many flush calls. 449 * 450 * Filesystems shouldn't assume that flush will always be called 451 * after some writes, or that if will be called at all. 452 * 453 * fi->fh will contain the value set by the open method, or will 454 * be undefined if the open method didn't set any value. 455 * 456 * NOTE: the name of the method is misleading, since (unlike 457 * fsync) the filesystem is not forced to flush pending writes. 458 * One reason to flush data, is if the filesystem wants to return 459 * write errors. 460 * 461 * If the filesystem supports file locking operations (setlk, 462 * getlk) it should remove all locks belonging to 'fi->owner'. 463 * 464 * Valid replies: 465 * fuse_reply_err 466 * 467 * @param req request handle 468 * @param ino the inode number 469 * @param fi file information 470 */ 471 void (*flush) (fuse_req_t req, fuse_ino_t ino, 472 struct fuse_file_info *fi); 473 474 /** 475 * Release an open file 476 * 477 * Release is called when there are no more references to an open 478 * file: all file descriptors are closed and all memory mappings 479 * are unmapped. 480 * 481 * For every open call there will be exactly one release call. 482 * 483 * The filesystem may reply with an error, but error values are 484 * not returned to close() or munmap() which triggered the 485 * release. 486 * 487 * fi->fh will contain the value set by the open method, or will 488 * be undefined if the open method didn't set any value. 489 * fi->flags will contain the same flags as for open. 490 * 491 * Valid replies: 492 * fuse_reply_err 493 * 494 * @param req request handle 495 * @param ino the inode number 496 * @param fi file information 497 */ 498 void (*release) (fuse_req_t req, fuse_ino_t ino, 499 struct fuse_file_info *fi); 500 501 /** 502 * Synchronize file contents 503 * 504 * If the datasync parameter is non-zero, then only the user data 505 * should be flushed, not the meta data. 506 * 507 * Valid replies: 508 * fuse_reply_err 509 * 510 * @param req request handle 511 * @param ino the inode number 512 * @param datasync flag indicating if only data should be flushed 513 * @param fi file information 514 */ 515 void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync, 516 struct fuse_file_info *fi); 517 518 /** 519 * Open a directory 520 * 521 * Filesystem may store an arbitrary file handle (pointer, index, 522 * etc) in fi->fh, and use this in other all other directory 523 * stream operations (readdir, releasedir, fsyncdir). 524 * 525 * Filesystem may also implement stateless directory I/O and not 526 * store anything in fi->fh, though that makes it impossible to 527 * implement standard conforming directory stream operations in 528 * case the contents of the directory can change between opendir 529 * and releasedir. 530 * 531 * Valid replies: 532 * fuse_reply_open 533 * fuse_reply_err 534 * 535 * @param req request handle 536 * @param ino the inode number 537 * @param fi file information 538 */ 539 void (*opendir) (fuse_req_t req, fuse_ino_t ino, 540 struct fuse_file_info *fi); 541 542 /** 543 * Read directory 544 * 545 * Send a buffer filled using fuse_add_direntry(), with size not 546 * exceeding the requested size. Send an empty buffer on end of 547 * stream. 548 * 549 * fi->fh will contain the value set by the opendir method, or 550 * will be undefined if the opendir method didn't set any value. 551 * 552 * Valid replies: 553 * fuse_reply_buf 554 * fuse_reply_err 555 * 556 * @param req request handle 557 * @param ino the inode number 558 * @param size maximum number of bytes to send 559 * @param off offset to continue reading the directory stream 560 * @param fi file information 561 */ 562 void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, 563 struct fuse_file_info *fi); 564 565 /** 566 * Release an open directory 567 * 568 * For every opendir call there will be exactly one releasedir 569 * call. 570 * 571 * fi->fh will contain the value set by the opendir method, or 572 * will be undefined if the opendir method didn't set any value. 573 * 574 * Valid replies: 575 * fuse_reply_err 576 * 577 * @param req request handle 578 * @param ino the inode number 579 * @param fi file information 580 */ 581 void (*releasedir) (fuse_req_t req, fuse_ino_t ino, 582 struct fuse_file_info *fi); 583 584 /** 585 * Synchronize directory contents 586 * 587 * If the datasync parameter is non-zero, then only the directory 588 * contents should be flushed, not the meta data. 589 * 590 * fi->fh will contain the value set by the opendir method, or 591 * will be undefined if the opendir method didn't set any value. 592 * 593 * Valid replies: 594 * fuse_reply_err 595 * 596 * @param req request handle 597 * @param ino the inode number 598 * @param datasync flag indicating if only data should be flushed 599 * @param fi file information 600 */ 601 void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync, 602 struct fuse_file_info *fi); 603 604 /** 605 * Get file system statistics 606 * 607 * Valid replies: 608 * fuse_reply_statfs 609 * fuse_reply_err 610 * 611 * @param req request handle 612 * @param ino the inode number, zero means "undefined" 613 */ 614 void (*statfs) (fuse_req_t req, fuse_ino_t ino); 615 616 /** 617 * Set an extended attribute 618 * 619 * Valid replies: 620 * fuse_reply_err 621 */ 622 void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name, 623 const char *value, size_t size, int flags); 624 625 /** 626 * Get an extended attribute 627 * 628 * If size is zero, the size of the value should be sent with 629 * fuse_reply_xattr. 630 * 631 * If the size is non-zero, and the value fits in the buffer, the 632 * value should be sent with fuse_reply_buf. 633 * 634 * If the size is too small for the value, the ERANGE error should 635 * be sent. 636 * 637 * Valid replies: 638 * fuse_reply_buf 639 * fuse_reply_xattr 640 * fuse_reply_err 641 * 642 * @param req request handle 643 * @param ino the inode number 644 * @param name of the extended attribute 645 * @param size maximum size of the value to send 646 */ 647 void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name, 648 size_t size); 649 650 /** 651 * List extended attribute names 652 * 653 * If size is zero, the total size of the attribute list should be 654 * sent with fuse_reply_xattr. 655 * 656 * If the size is non-zero, and the null character separated 657 * attribute list fits in the buffer, the list should be sent with 658 * fuse_reply_buf. 659 * 660 * If the size is too small for the list, the ERANGE error should 661 * be sent. 662 * 663 * Valid replies: 664 * fuse_reply_buf 665 * fuse_reply_xattr 666 * fuse_reply_err 667 * 668 * @param req request handle 669 * @param ino the inode number 670 * @param size maximum size of the list to send 671 */ 672 void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size); 673 674 /** 675 * Remove an extended attribute 676 * 677 * Valid replies: 678 * fuse_reply_err 679 * 680 * @param req request handle 681 * @param ino the inode number 682 * @param name of the extended attribute 683 */ 684 void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name); 685 686 /** 687 * Check file access permissions 688 * 689 * This will be called for the access() system call. If the 690 * 'default_permissions' mount option is given, this method is not 691 * called. 692 * 693 * This method is not called under Linux kernel versions 2.4.x 694 * 695 * Introduced in version 2.5 696 * 697 * Valid replies: 698 * fuse_reply_err 699 * 700 * @param req request handle 701 * @param ino the inode number 702 * @param mask requested access mode 703 */ 704 void (*access) (fuse_req_t req, fuse_ino_t ino, int mask); 705 706 /** 707 * Create and open a file 708 * 709 * If the file does not exist, first create it with the specified 710 * mode, and then open it. 711 * 712 * Open flags (with the exception of O_NOCTTY) are available in 713 * fi->flags. 714 * 715 * Filesystem may store an arbitrary file handle (pointer, index, 716 * etc) in fi->fh, and use this in other all other file operations 717 * (read, write, flush, release, fsync). 718 * 719 * There are also some flags (direct_io, keep_cache) which the 720 * filesystem may set in fi, to change the way the file is opened. 721 * See fuse_file_info structure in <fuse_common.h> for more details. 722 * 723 * If this method is not implemented or under Linux kernel 724 * versions earlier than 2.6.15, the mknod() and open() methods 725 * will be called instead. 726 * 727 * Introduced in version 2.5 728 * 729 * Valid replies: 730 * fuse_reply_create 731 * fuse_reply_err 732 * 733 * @param req request handle 734 * @param parent inode number of the parent directory 735 * @param name to create 736 * @param mode file type and mode with which to create the new file 737 * @param fi file information 738 */ 739 void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name, 740 mode_t mode, struct fuse_file_info *fi); 741 742 /** 743 * Test for a POSIX file lock 744 * 745 * Introduced in version 2.6 746 * 747 * Valid replies: 748 * fuse_reply_lock 749 * fuse_reply_err 750 * 751 * @param req request handle 752 * @param ino the inode number 753 * @param fi file information 754 * @param lock the region/type to test 755 */ 756 void (*getlk) (fuse_req_t req, fuse_ino_t ino, 757 struct fuse_file_info *fi, struct flock *lock); 758 759 /** 760 * Acquire, modify or release a POSIX file lock 761 * 762 * For POSIX threads (NPTL) there's a 1-1 relation between pid and 763 * owner, but otherwise this is not always the case. For checking 764 * lock ownership, 'fi->owner' must be used. The l_pid field in 765 * 'struct flock' should only be used to fill in this field in 766 * getlk(). 767 * 768 * Note: if the locking methods are not implemented, the kernel 769 * will still allow file locking to work locally. Hence these are 770 * only interesting for network filesystems and similar. 771 * 772 * Introduced in version 2.6 773 * 774 * Valid replies: 775 * fuse_reply_err 776 * 777 * @param req request handle 778 * @param ino the inode number 779 * @param fi file information 780 * @param lock the region/type to test 781 * @param sleep locking operation may sleep 782 */ 783 void (*setlk) (fuse_req_t req, fuse_ino_t ino, 784 struct fuse_file_info *fi, 785 struct flock *lock, int sleep); 786 787 /** 788 * Map block index within file to block index within device 789 * 790 * Note: This makes sense only for block device backed filesystems 791 * mounted with the 'blkdev' option 792 * 793 * Introduced in version 2.6 794 * 795 * Valid replies: 796 * fuse_reply_bmap 797 * fuse_reply_err 798 * 799 * @param req request handle 800 * @param ino the inode number 801 * @param blocksize unit of block index 802 * @param idx block index within file 803 */ 804 void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize, 805 uint64_t idx); 806 /** 807 * Ioctl 808 * 809 * Note: For unrestricted ioctls (not allowed for FUSE 810 * servers), data in and out areas can be discovered by giving 811 * iovs and setting FUSE_IOCTL_RETRY in @flags. For 812 * restricted ioctls, kernel prepares in/out data area 813 * according to the information encoded in cmd. 814 * 815 * Introduced in version 2.8 816 * 817 * Note : the unsigned long request submitted by the application 818 * is truncated to 32 bits, and forwarded as a signed int. 819 * 820 * Valid replies: 821 * fuse_reply_ioctl_retry 822 * fuse_reply_ioctl 823 * fuse_reply_ioctl_iov 824 * fuse_reply_err 825 * 826 * @param req request handle 827 * @param ino the inode number 828 * @param cmd ioctl command 829 * @param arg ioctl argument 830 * @param fi file information 831 * @param flags for FUSE_IOCTL_* flags 832 * @param in_buf data fetched from the caller 833 * @param in_bufsz number of fetched bytes 834 * @param out_bufsz maximum size of output data 835 */ 836 void (*ioctl) (fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, 837 struct fuse_file_info *fi, unsigned flags, 838 const void *in_buf, size_t in_bufsz, size_t out_bufsz); 839 840 }; 841 842 /** 843 * Reply with an error code or success 844 * 845 * Possible requests: 846 * all except forget 847 * 848 * unlink, rmdir, rename, flush, release, fsync, fsyncdir, setxattr, 849 * removexattr and setlk may send a zero code 850 * 851 * @param req request handle 852 * @param err the positive error value, or zero for success 853 * @return zero for success, -errno for failure to send reply 854 */ 855 int fuse_reply_err(fuse_req_t req, int err); 856 857 /** 858 * Don't send reply 859 * 860 * Possible requests: 861 * forget 862 * 863 * @param req request handle 864 */ 865 void fuse_reply_none(fuse_req_t req); 866 867 /** 868 * Reply with a directory entry 869 * 870 * Possible requests: 871 * lookup, mknod, mkdir, symlink, link 872 * 873 * @param req request handle 874 * @param e the entry parameters 875 * @return zero for success, -errno for failure to send reply 876 */ 877 int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e); 878 879 /** 880 * Reply with a directory entry and open parameters 881 * 882 * currently the following members of 'fi' are used: 883 * fh, direct_io, keep_cache 884 * 885 * Possible requests: 886 * create 887 * 888 * @param req request handle 889 * @param e the entry parameters 890 * @param fi file information 891 * @return zero for success, -errno for failure to send reply 892 */ 893 int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e, 894 const struct fuse_file_info *fi); 895 896 /** 897 * Reply with attributes 898 * 899 * Possible requests: 900 * getattr, setattr 901 * 902 * @param req request handle 903 * @param the attributes 904 * @param attr_timeout validity timeout (in seconds) for the attributes 905 * @return zero for success, -errno for failure to send reply 906 */ 907 int fuse_reply_attr(fuse_req_t req, const struct stat *attr, 908 double attr_timeout); 909 910 /** 911 * Reply with the contents of a symbolic link 912 * 913 * Possible requests: 914 * readlink 915 * 916 * @param req request handle 917 * @param link symbolic link contents 918 * @return zero for success, -errno for failure to send reply 919 */ 920 int fuse_reply_readlink(fuse_req_t req, const char *link); 921 922 /** 923 * Reply with open parameters 924 * 925 * currently the following members of 'fi' are used: 926 * fh, direct_io, keep_cache 927 * 928 * Possible requests: 929 * open, opendir 930 * 931 * @param req request handle 932 * @param fi file information 933 * @return zero for success, -errno for failure to send reply 934 */ 935 int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi); 936 937 /** 938 * Reply with number of bytes written 939 * 940 * Possible requests: 941 * write 942 * 943 * @param req request handle 944 * @param count the number of bytes written 945 * @return zero for success, -errno for failure to send reply 946 */ 947 int fuse_reply_write(fuse_req_t req, size_t count); 948 949 /** 950 * Reply with data 951 * 952 * Possible requests: 953 * read, readdir, getxattr, listxattr 954 * 955 * @param req request handle 956 * @param buf buffer containing data 957 * @param size the size of data in bytes 958 * @return zero for success, -errno for failure to send reply 959 */ 960 int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size); 961 962 #ifdef POSIXACLS 963 /** 964 * Reply with data vector 965 * 966 * Possible requests: 967 * read, readdir, getxattr, listxattr 968 * 969 * @param req request handle 970 * @param iov the vector containing the data 971 * @param count the size of vector 972 * @return zero for success, -errno for failure to send reply 973 */ 974 int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count); 975 #endif 976 977 /** 978 * Reply with filesystem statistics 979 * 980 * Possible requests: 981 * statfs 982 * 983 * @param req request handle 984 * @param stbuf filesystem statistics 985 * @return zero for success, -errno for failure to send reply 986 */ 987 int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf); 988 989 /** 990 * Reply with needed buffer size 991 * 992 * Possible requests: 993 * getxattr, listxattr 994 * 995 * @param req request handle 996 * @param count the buffer size needed in bytes 997 * @return zero for success, -errno for failure to send reply 998 */ 999 int fuse_reply_xattr(fuse_req_t req, size_t count); 1000 1001 /** 1002 * Reply with file lock information 1003 * 1004 * Possible requests: 1005 * getlk 1006 * 1007 * @param req request handle 1008 * @param lock the lock information 1009 * @return zero for success, -errno for failure to send reply 1010 */ 1011 int fuse_reply_lock(fuse_req_t req, struct flock *lock); 1012 1013 /** 1014 * Reply with block index 1015 * 1016 * Possible requests: 1017 * bmap 1018 * 1019 * @param req request handle 1020 * @param idx block index within device 1021 * @return zero for success, -errno for failure to send reply 1022 */ 1023 int fuse_reply_bmap(fuse_req_t req, uint64_t idx); 1024 1025 /* ----------------------------------------------------------- * 1026 * Filling a buffer in readdir * 1027 * ----------------------------------------------------------- */ 1028 1029 /** 1030 * Add a directory entry to the buffer 1031 * 1032 * Buffer needs to be large enough to hold the entry. Of it's not, 1033 * then the entry is not filled in but the size of the entry is still 1034 * returned. The caller can check this by comparing the bufsize 1035 * parameter with the returned entry size. If the entry size is 1036 * larger than the buffer size, the operation failed. 1037 * 1038 * From the 'stbuf' argument the st_ino field and bits 12-15 of the 1039 * st_mode field are used. The other fields are ignored. 1040 * 1041 * Note: offsets do not necessarily represent physical offsets, and 1042 * could be any marker, that enables the implementation to find a 1043 * specific point in the directory stream. 1044 * 1045 * @param req request handle 1046 * @param buf the point where the new entry will be added to the buffer 1047 * @param bufsize remaining size of the buffer 1048 * @param the name of the entry 1049 * @param stbuf the file attributes 1050 * @param off the offset of the next entry 1051 * @return the space needed for the entry 1052 */ 1053 size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize, 1054 const char *name, const struct stat *stbuf, 1055 off_t off); 1056 1057 /** 1058 * Reply to finish ioctl 1059 * 1060 * Possible requests: 1061 * ioctl 1062 * 1063 * @param req request handle 1064 * @param result result to be passed to the caller 1065 * @param buf buffer containing output data 1066 * @param size length of output data 1067 */ 1068 int fuse_reply_ioctl(fuse_req_t req, int result, const void *buf, size_t size); 1069 1070 1071 /* ----------------------------------------------------------- * 1072 * Utility functions * 1073 * ----------------------------------------------------------- */ 1074 1075 /** 1076 * Get the userdata from the request 1077 * 1078 * @param req request handle 1079 * @return the user data passed to fuse_lowlevel_new() 1080 */ 1081 void *fuse_req_userdata(fuse_req_t req); 1082 1083 /** 1084 * Get the context from the request 1085 * 1086 * The pointer returned by this function will only be valid for the 1087 * request's lifetime 1088 * 1089 * @param req request handle 1090 * @return the context structure 1091 */ 1092 const struct fuse_ctx *fuse_req_ctx(fuse_req_t req); 1093 1094 /** 1095 * Callback function for an interrupt 1096 * 1097 * @param req interrupted request 1098 * @param data user data 1099 */ 1100 typedef void (*fuse_interrupt_func_t)(fuse_req_t req, void *data); 1101 1102 /** 1103 * Register/unregister callback for an interrupt 1104 * 1105 * If an interrupt has already happened, then the callback function is 1106 * called from within this function, hence it's not possible for 1107 * interrupts to be lost. 1108 * 1109 * @param req request handle 1110 * @param func the callback function or NULL for unregister 1111 * @parm data user data passed to the callback function 1112 */ 1113 void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func, 1114 void *data); 1115 1116 /** 1117 * Check if a request has already been interrupted 1118 * 1119 * @param req request handle 1120 * @return 1 if the request has been interrupted, 0 otherwise 1121 */ 1122 int fuse_req_interrupted(fuse_req_t req); 1123 1124 /* ----------------------------------------------------------- * 1125 * Filesystem setup * 1126 * ----------------------------------------------------------- */ 1127 1128 #ifdef __SOLARIS__ 1129 1130 /* Deprecated, don't use */ 1131 int fuse_lowlevel_is_lib_option(const char *opt); 1132 1133 #endif /* __SOLARIS__ */ 1134 1135 /** 1136 * Create a low level session 1137 * 1138 * @param args argument vector 1139 * @param op the low level filesystem operations 1140 * @param op_size sizeof(struct fuse_lowlevel_ops) 1141 * @param userdata user data 1142 * @return the created session object, or NULL on failure 1143 */ 1144 struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, 1145 const struct fuse_lowlevel_ops *op, 1146 size_t op_size, void *userdata); 1147 1148 /* ----------------------------------------------------------- * 1149 * Session interface * 1150 * ----------------------------------------------------------- */ 1151 1152 /** 1153 * Session operations 1154 * 1155 * This is used in session creation 1156 */ 1157 struct fuse_session_ops { 1158 /** 1159 * Hook to process a request (mandatory) 1160 * 1161 * @param data user data passed to fuse_session_new() 1162 * @param buf buffer containing the raw request 1163 * @param len request length 1164 * @param ch channel on which the request was received 1165 */ 1166 void (*process) (void *data, const char *buf, size_t len, 1167 struct fuse_chan *ch); 1168 1169 /** 1170 * Hook for session exit and reset (optional) 1171 * 1172 * @param data user data passed to fuse_session_new() 1173 * @param val exited status (1 - exited, 0 - not exited) 1174 */ 1175 void (*exit) (void *data, int val); 1176 1177 /** 1178 * Hook for querying the current exited status (optional) 1179 * 1180 * @param data user data passed to fuse_session_new() 1181 * @return 1 if exited, 0 if not exited 1182 */ 1183 int (*exited) (void *data); 1184 1185 /** 1186 * Hook for cleaning up the channel on destroy (optional) 1187 * 1188 * @param data user data passed to fuse_session_new() 1189 */ 1190 void (*destroy) (void *data); 1191 }; 1192 1193 /** 1194 * Create a new session 1195 * 1196 * @param op session operations 1197 * @param data user data 1198 * @return new session object, or NULL on failure 1199 */ 1200 struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data); 1201 1202 /** 1203 * Assign a channel to a session 1204 * 1205 * Note: currently only a single channel may be assigned. This may 1206 * change in the future 1207 * 1208 * If a session is destroyed, the assigned channel is also destroyed 1209 * 1210 * @param se the session 1211 * @param ch the channel 1212 */ 1213 void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch); 1214 1215 /** 1216 * Remove a channel from a session 1217 * 1218 * If the channel is not assigned to a session, then this is a no-op 1219 * 1220 * @param ch the channel to remove 1221 */ 1222 void fuse_session_remove_chan(struct fuse_chan *ch); 1223 1224 /** 1225 * Iterate over the channels assigned to a session 1226 * 1227 * The iterating function needs to start with a NULL channel, and 1228 * after that needs to pass the previously returned channel to the 1229 * function. 1230 * 1231 * @param se the session 1232 * @param ch the previous channel, or NULL 1233 * @return the next channel, or NULL if no more channels exist 1234 */ 1235 struct fuse_chan *fuse_session_next_chan(struct fuse_session *se, 1236 struct fuse_chan *ch); 1237 1238 /** 1239 * Process a raw request 1240 * 1241 * @param se the session 1242 * @param buf buffer containing the raw request 1243 * @param len request length 1244 * @param ch channel on which the request was received 1245 */ 1246 void fuse_session_process(struct fuse_session *se, const char *buf, size_t len, 1247 struct fuse_chan *ch); 1248 1249 /** 1250 * Destroy a session 1251 * 1252 * @param se the session 1253 */ 1254 void fuse_session_destroy(struct fuse_session *se); 1255 1256 /** 1257 * Exit a session 1258 * 1259 * @param se the session 1260 */ 1261 void fuse_session_exit(struct fuse_session *se); 1262 1263 /** 1264 * Reset the exited status of a session 1265 * 1266 * @param se the session 1267 */ 1268 void fuse_session_reset(struct fuse_session *se); 1269 1270 /** 1271 * Query the exited status of a session 1272 * 1273 * @param se the session 1274 * @return 1 if exited, 0 if not exited 1275 */ 1276 int fuse_session_exited(struct fuse_session *se); 1277 1278 /** 1279 * Enter a single threaded event loop 1280 * 1281 * @param se the session 1282 * @return 0 on success, -1 on error 1283 */ 1284 int fuse_session_loop(struct fuse_session *se); 1285 1286 /** 1287 * Enter a multi-threaded event loop 1288 * 1289 * @param se the session 1290 * @return 0 on success, -1 on error 1291 */ 1292 int fuse_session_loop_mt(struct fuse_session *se); 1293 1294 /* ----------------------------------------------------------- * 1295 * Channel interface * 1296 * ----------------------------------------------------------- */ 1297 1298 /** 1299 * Channel operations 1300 * 1301 * This is used in channel creation 1302 */ 1303 struct fuse_chan_ops { 1304 /** 1305 * Hook for receiving a raw request 1306 * 1307 * @param ch pointer to the channel 1308 * @param buf the buffer to store the request in 1309 * @param size the size of the buffer 1310 * @return the actual size of the raw request, or -1 on error 1311 */ 1312 int (*receive)(struct fuse_chan **chp, char *buf, size_t size); 1313 1314 /** 1315 * Hook for sending a raw reply 1316 * 1317 * A return value of -ENOENT means, that the request was 1318 * interrupted, and the reply was discarded 1319 * 1320 * @param ch the channel 1321 * @param iov vector of blocks 1322 * @param count the number of blocks in vector 1323 * @return zero on success, -errno on failure 1324 */ 1325 int (*send)(struct fuse_chan *ch, const struct iovec iov[], 1326 size_t count); 1327 1328 /** 1329 * Destroy the channel 1330 * 1331 * @param ch the channel 1332 */ 1333 void (*destroy)(struct fuse_chan *ch); 1334 }; 1335 1336 /** 1337 * Create a new channel 1338 * 1339 * @param op channel operations 1340 * @param fd file descriptor of the channel 1341 * @param bufsize the minimal receive buffer size 1342 * @param data user data 1343 * @return the new channel object, or NULL on failure 1344 */ 1345 struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd, 1346 size_t bufsize, void *data); 1347 1348 /** 1349 * Query the file descriptor of the channel 1350 * 1351 * @param ch the channel 1352 * @return the file descriptor passed to fuse_chan_new() 1353 */ 1354 int fuse_chan_fd(struct fuse_chan *ch); 1355 1356 /** 1357 * Query the minimal receive buffer size 1358 * 1359 * @param ch the channel 1360 * @return the buffer size passed to fuse_chan_new() 1361 */ 1362 size_t fuse_chan_bufsize(struct fuse_chan *ch); 1363 1364 /** 1365 * Query the user data 1366 * 1367 * @param ch the channel 1368 * @return the user data passed to fuse_chan_new() 1369 */ 1370 void *fuse_chan_data(struct fuse_chan *ch); 1371 1372 /** 1373 * Query the session to which this channel is assigned 1374 * 1375 * @param ch the channel 1376 * @return the session, or NULL if the channel is not assigned 1377 */ 1378 struct fuse_session *fuse_chan_session(struct fuse_chan *ch); 1379 1380 /** 1381 * Receive a raw request 1382 * 1383 * A return value of -ENODEV means, that the filesystem was unmounted 1384 * 1385 * @param ch pointer to the channel 1386 * @param buf the buffer to store the request in 1387 * @param size the size of the buffer 1388 * @return the actual size of the raw request, or -errno on error 1389 */ 1390 int fuse_chan_recv(struct fuse_chan **ch, char *buf, size_t size); 1391 1392 /** 1393 * Send a raw reply 1394 * 1395 * A return value of -ENOENT means, that the request was 1396 * interrupted, and the reply was discarded 1397 * 1398 * @param ch the channel 1399 * @param iov vector of blocks 1400 * @param count the number of blocks in vector 1401 * @return zero on success, -errno on failure 1402 */ 1403 int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], 1404 size_t count); 1405 1406 /** 1407 * Destroy a channel 1408 * 1409 * @param ch the channel 1410 */ 1411 void fuse_chan_destroy(struct fuse_chan *ch); 1412 1413 #ifdef __cplusplus 1414 } 1415 #endif 1416 1417 #endif /* _FUSE_LOWLEVEL_H_ */ 1418