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