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