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