aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]doc/Doxyfile8
-rwxr-xr-x[-rw-r--r--]doc/how-fuse-works0
-rw-r--r--doc/images/490px-FUSE_structure.svg.pngbin0 -> 22606 bytes
-rwxr-xr-xdoc/mainpage.dox92
-rwxr-xr-x[-rw-r--r--]example/cusexmp.c15
-rwxr-xr-x[-rw-r--r--]example/fioc.c15
-rwxr-xr-x[-rw-r--r--]example/fioc.h9
-rwxr-xr-x[-rw-r--r--]example/fioclient.c17
-rwxr-xr-x[-rw-r--r--]example/fsel.c15
-rwxr-xr-x[-rw-r--r--]example/fselclient.c15
-rwxr-xr-x[-rw-r--r--]example/fusexmp.c16
-rwxr-xr-x[-rw-r--r--]example/fusexmp_fh.c15
-rwxr-xr-x[-rw-r--r--]example/hello.c31
-rwxr-xr-x[-rw-r--r--]example/hello_ll.c41
-rwxr-xr-x[-rw-r--r--]example/null.c15
-rw-r--r--include/fuse.h23
-rw-r--r--include/fuse_common.h9
-rw-r--r--include/fuse_lowlevel.h13
-rwxr-xr-x[-rw-r--r--]lib/fuse_loop_mt.c0
-rw-r--r--lib/fuse_signals.c2
20 files changed, 327 insertions, 24 deletions
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 3926aaf..16ce23a 100644..100755
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -544,7 +544,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = include
+INPUT = . ../include ../example ../lib
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -561,7 +561,7 @@ INPUT_ENCODING = UTF-8
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-FILE_PATTERNS = *.h
+FILE_PATTERNS = *.h *.c *.h *.dox
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
@@ -601,7 +601,7 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see
# the \include command).
-EXAMPLE_PATH =
+EXAMPLE_PATH = . ../example/ ../lib
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@@ -621,7 +621,7 @@ EXAMPLE_RECURSIVE = NO
# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH =
+IMAGE_PATH = images/
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/doc/how-fuse-works b/doc/how-fuse-works
index a5febe3..a5febe3 100644..100755
--- a/doc/how-fuse-works
+++ b/doc/how-fuse-works
diff --git a/doc/images/490px-FUSE_structure.svg.png b/doc/images/490px-FUSE_structure.svg.png
new file mode 100644
index 0000000..a4a9731
--- /dev/null
+++ b/doc/images/490px-FUSE_structure.svg.png
Binary files differ
diff --git a/doc/mainpage.dox b/doc/mainpage.dox
new file mode 100755
index 0000000..9202207
--- /dev/null
+++ b/doc/mainpage.dox
@@ -0,0 +1,92 @@
+/*!
+\mainpage FUSE API documentation
+
+Filesystem in Userspace (FUSE) is a loadable kernel module for Unix-like computer operating systems that lets non-privileged users create their own file systems without editing kernel code. This is achieved by running file system code in user space while the FUSE module provides only a "bridge" to the actual kernel interfaces.
+
+(c) Wikipedia
+
+@tableofcontents
+
+
+
+
+
+\section section1 How FUSE works
+
+@image html 490px-FUSE_structure.svg.png "Structural diagramm of Filesystem in Userspace from http://en.wikipedia.org/wiki/File:FUSE_structure.svg"
+
+\include how-fuse-works
+
+
+
+
+\section section2 Kernel
+
+\include kernel.txt
+
+
+
+
+
+\section section_examples examples
+
+have a look at the examples listed in the example directory, which can be found here: <a href="files.html">files.html</a>.
+
+- @ref hello.c - minimal FUSE example featuring fuse_main usage
+
+- @ref hello_ll.c - FUSE: Filesystem in Userspace
+
+- @ref null.c - FUSE: Filesystem in Userspace
+
+- @ref cusexmp.c - CUSE example: Character device in Userspace
+
+- @ref fioc.c - FUSE fioc: FUSE ioctl example
+
+- @ref fioclient.c - FUSE fioclient: FUSE ioctl example client
+
+- @ref fsel.c - FUSE fsel: FUSE select example
+
+- @ref fselclient.c - FUSE fselclient: FUSE select example client
+
+- @ref fusexmp.c - FUSE: Filesystem in Userspace
+
+- @ref fusexmp_fh.c - FUSE: Filesystem in Userspace
+
+
+\section section_links links
+
+<a href="http://sourceforge.net/apps/mediawiki/fuse/index.php?title=Main_Page">http://sourceforge.net/apps/mediawiki/fuse/index.php?title=Main_Page</a> - the fuse wiki
+
+<a href="http://en.wikipedia.org/wiki/Filesystem_in_Userspace">http://en.wikipedia.org/wiki/Filesystem_in_Userspace</a> - FUSE on wikipedia
+
+
+\section section_todo todo
+
+general:
+
+ - fuse_lowlevel.h, describe:
+ - a channel (or communication channel) is created by fuse_mount(..)
+ - a fuse session is associated with a channel and a signal handler and runs until the assigned signal handler
+ shuts the session down, see fuse_session_loop(se) and hello_ll.c
+
+ - http://www.cs.nmsu.edu/~pfeiffer/fuse-tutorial/
+
+ - http://cinwell.wordpress.com/
+
+ - http://sourceforge.net/apps/mediawiki/fuse/index.php?title=FuseProtocolSketch
+
+ - http://muratbuffalo.blogspot.de/2011/05/refuse-to-crash-with-re-fuse.html
+
+examples:
+ - demonstrate the effect of single vs multithreaded -> fuse_loop fuse_loop_mt
+
+ - add comments and source form all existing examples
+
+ - also add examples form here: http://sourceforge.net/apps/mediawiki/fuse/index.php?title=Main_Page#How_should_threads_be_startedx3f
+
+ - add this new example: http://fuse.996288.n3.nabble.com/Create-multiple-filesystems-in-same-process-td9292.html
+
+ \section section_thanks thanks
+ - Mark Glines, <mark@glines.org> for his coments on fuse_loop() and fuse_loop_mt().
+ - Wikipedia - copied the FUSE introduction from the Filesystem in userspace article.
+*/
diff --git a/example/cusexmp.c b/example/cusexmp.c
index b69f97c..a02818c 100644..100755
--- a/example/cusexmp.c
+++ b/example/cusexmp.c
@@ -6,9 +6,22 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
- gcc -Wall cusexmp.c `pkg-config fuse --cflags --libs` -o cusexmp
*/
+/** @file
+ * @tableofcontents
+ *
+ * cusexmp.c - CUSE example: Character device in Userspace
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall cusexmp.c `pkg-config fuse --cflags --libs` -o cusexmp
+ *
+ * \section section_source the complete source
+ * \include cusexmp.c
+ */
+
+
#define FUSE_USE_VERSION 30
#include <cuse_lowlevel.h>
diff --git a/example/fioc.c b/example/fioc.c
index 849bd5d..cfb18ae 100644..100755
--- a/example/fioc.c
+++ b/example/fioc.c
@@ -6,9 +6,22 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
- gcc -Wall fioc.c `pkg-config fuse --cflags --libs` -o fioc
*/
+/** @file
+ * @tableofcontents
+ *
+ * fioc.c - FUSE fioc: FUSE ioctl example
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall fioc.c `pkg-config fuse --cflags --libs` -o fioc
+ *
+ * \section section_source the complete source
+ * \include fioc.c
+ */
+
+
#define FUSE_USE_VERSION 30
#include <fuse.h>
diff --git a/example/fioc.h b/example/fioc.h
index ec1a39d..c9bf358 100644..100755
--- a/example/fioc.h
+++ b/example/fioc.h
@@ -7,6 +7,15 @@
See the file COPYING.
*/
+/** @file
+ * @tableofcontents
+ *
+ * fioc.h - FUSE-ioctl: ioctl support for FUSE
+ *
+ * \include fioc.h
+ */
+
+
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
diff --git a/example/fioclient.c b/example/fioclient.c
index 5f05525..9718622 100644..100755
--- a/example/fioclient.c
+++ b/example/fioclient.c
@@ -5,10 +5,23 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
-
- gcc -Wall fioclient.c -o fioclient
*/
+/** @file
+ * @tableofcontents
+ *
+ * fioclient.c - FUSE fioclient: FUSE ioctl example client
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall fioclient.c -o fioclient
+ *
+ * \section section_source the complete source
+ * fioclient.c
+ * \include fioclient.c
+ */
+
+
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
diff --git a/example/fsel.c b/example/fsel.c
index bddc1aa..3c52033 100644..100755
--- a/example/fsel.c
+++ b/example/fsel.c
@@ -6,9 +6,22 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
- gcc -Wall fsel.c `pkg-config fuse --cflags --libs` -o fsel
*/
+/** @file
+ * @tableofcontents
+ *
+ * fsel.c - FUSE fsel: FUSE select example
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall fsel.c `pkg-config fuse --cflags --libs` -o fsel
+ *
+ * \section section_source the complete source
+ * \include fsel.c
+ */
+
+
#define FUSE_USE_VERSION 30
#include <fuse.h>
diff --git a/example/fselclient.c b/example/fselclient.c
index 7c4b837..2e2e571 100644..100755
--- a/example/fselclient.c
+++ b/example/fselclient.c
@@ -6,9 +6,22 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
- gcc -Wall fselclient.c -o fselclient
*/
+/** @file
+ * @tableofcontents
+ *
+ * fselclient.c - FUSE fselclient: FUSE select example client
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall fselclient.c -o fselclient
+ *
+ * \section section_source the complete source
+ * \include fselclient.c
+ */
+
+
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
diff --git a/example/fusexmp.c b/example/fusexmp.c
index 42a8134..73e9898 100644..100755
--- a/example/fusexmp.c
+++ b/example/fusexmp.c
@@ -5,10 +5,22 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
-
- gcc -Wall fusexmp.c `pkg-config fuse --cflags --libs` -o fusexmp
*/
+/** @file
+ * @tableofcontents
+ *
+ * fusexmp.c - FUSE: Filesystem in Userspace
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall fusexmp.c `pkg-config fuse --cflags --libs` -o fusexmp
+ *
+ * \section section_source the complete source
+ * \include fusexmp.c
+ */
+
+
#define FUSE_USE_VERSION 30
#ifdef HAVE_CONFIG_H
diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c
index eea6b9b..e538b49 100644..100755
--- a/example/fusexmp_fh.c
+++ b/example/fusexmp_fh.c
@@ -5,10 +5,21 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
-
- gcc -Wall fusexmp_fh.c `pkg-config fuse --cflags --libs` -lulockmgr -o fusexmp_fh
*/
+/** @file
+ * @tableofcontents
+ *
+ * fusexmp_fh.c - FUSE: Filesystem in Userspace
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall fusexmp_fh.c `pkg-config fuse --cflags --libs` -lulockmgr -o fusexmp_fh
+ *
+ * \section section_source the complete source
+ * \include fusexmp_fh.c
+ */
+
#define FUSE_USE_VERSION 30
#ifdef HAVE_CONFIG_H
diff --git a/example/hello.c b/example/hello.c
index b31fbe5..c8b4a48 100644..100755
--- a/example/hello.c
+++ b/example/hello.c
@@ -4,10 +4,35 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
-
- gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello
*/
+/** @file
+ *
+ * hello.c - minimal FUSE example featuring fuse_main usage
+ *
+* \section section_compile compiling this example
+ *
+ * gcc -Wall hello.c `pkg-config fuse --cflags --libs` -o hello
+ *
+ * \section section_usage usage
+ \verbatim
+ % mkdir mnt
+ % ./hello mnt # program will vanish into the background
+ % ls -la mnt
+ total 4
+ drwxr-xr-x 2 root root 0 Jan 1 1970 ./
+ drwxrwx--- 1 root vboxsf 4096 Jun 16 23:12 ../
+ -r--r--r-- 1 root root 13 Jan 1 1970 hello
+ % cat mnt/hello
+ Hello World!
+ % fusermount -u mnt
+ \endverbatim
+ *
+ * \section section_source the complete source
+ * \include hello.c
+ */
+
+
#define FUSE_USE_VERSION 30
#include <fuse.h>
@@ -83,6 +108,7 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset,
return size;
}
+// fuse_operations hello_oper is redirecting function-calls to _our_ functions implemented above
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
@@ -90,6 +116,7 @@ static struct fuse_operations hello_oper = {
.read = hello_read,
};
+// in the main function we call the blocking fuse_main(..) function with &hello_oper
int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper, NULL);
diff --git a/example/hello_ll.c b/example/hello_ll.c
index baf41bc..687c6f1 100644..100755
--- a/example/hello_ll.c
+++ b/example/hello_ll.c
@@ -4,10 +4,39 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
-
- gcc -Wall hello_ll.c `pkg-config fuse --cflags --libs` -o hello_ll
*/
+/** @file
+ *
+ * hello_ll.c - fuse low level functionality
+ *
+ * unlike hello.c this example will stay in the foreground. it also replaced
+ * the convenience function fuse_main(..) with a more low level approach.
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall hello_ll.c `pkg-config fuse --cflags --libs` -o hello_ll
+ *
+ * \section section_usage usage
+ \verbatim
+ % mkdir mnt
+ % ./hello_ll mnt # program will wait in foreground until you press CTRL+C
+ in a different shell do:
+ % ls -la mnt
+ total 4
+ drwxr-xr-x 2 root root 0 Jan 1 1970 ./
+ drwxrwx--- 1 root vboxsf 4096 Jun 16 23:12 ../
+ -r--r--r-- 1 root root 13 Jan 1 1970 hello
+ % cat mnt/hello
+ Hello World!
+ finally either press ctrl+c or do:
+ % fusermount -u mnt
+ \endverbatim
+ *
+ * \section section_source the complete source
+ * \include hello_ll.c
+ */
+
#define FUSE_USE_VERSION 30
#include <fuse_lowlevel.h>
@@ -151,6 +180,7 @@ static struct fuse_lowlevel_ops hello_ll_oper = {
.read = hello_ll_read,
};
+//! [doxygen_fuse_lowlevel_usage]
int main(int argc, char *argv[])
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
@@ -161,13 +191,15 @@ int main(int argc, char *argv[])
if (fuse_parse_cmdline(&args, &mountpoint, NULL, NULL) != -1 &&
(ch = fuse_mount(mountpoint, &args)) != NULL) {
struct fuse_session *se;
-
se = fuse_lowlevel_new(&args, &hello_ll_oper,
sizeof(hello_ll_oper), NULL);
if (se != NULL) {
if (fuse_set_signal_handlers(se) != -1) {
fuse_session_add_chan(se, ch);
- err = fuse_session_loop(se);
+
+ // fuse_session_loop(..) blocks until ctrl+c or fusermount -u
+ err = fuse_session_loop(se);
+
fuse_remove_signal_handlers(se);
fuse_session_remove_chan(ch);
}
@@ -179,3 +211,4 @@ int main(int argc, char *argv[])
return err ? 1 : 0;
}
+//! [doxygen_fuse_lowlevel_usage]
diff --git a/example/null.c b/example/null.c
index 4e2bb8f..6952333 100644..100755
--- a/example/null.c
+++ b/example/null.c
@@ -4,10 +4,21 @@
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
-
- gcc -Wall null.c `pkg-config fuse --cflags --libs` -o null
*/
+/** @file
+ *
+ * null.c - FUSE: Filesystem in Userspace
+ *
+ * \section section_compile compiling this example
+ *
+ * gcc -Wall null.c `pkg-config fuse --cflags --libs` -o null
+ *
+ * \section section_source the complete source
+ * \include null.c
+ */
+
+
#define FUSE_USE_VERSION 30
#include <fuse.h>
diff --git a/include/fuse.h b/include/fuse.h
index 793862e..c7647ce 100644
--- a/include/fuse.h
+++ b/include/fuse.h
@@ -589,6 +589,8 @@ struct fuse_context {
* @param op the file system operation
* @param user_data user data supplied in the context during the init() method
* @return 0 on success, nonzero on failure
+ *
+ * Example usage, see hello.c
*/
/*
int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
@@ -635,6 +637,8 @@ void fuse_destroy(struct fuse *f);
*
* @param f the FUSE handle
* @return 0 if no error occurred, -1 otherwise
+ *
+ * See also: fuse_loop()
*/
int fuse_loop(struct fuse *f);
@@ -654,9 +658,28 @@ void fuse_exit(struct fuse *f);
*
* Calling this function requires the pthreads library to be linked to
* the application.
+ *
+ * Note: using fuse_loop() instead of fuse_loop_mt() means you are running in single-threaded mode,
+ * and that you will not have to worry about reentrancy,
+ * though you will have to worry about recursive lookups. In single-threaded mode, FUSE
+ * holds a global lock on your filesystem, and will wait for one callback to return
+ * before calling another. This can lead to deadlocks, if your script makes any attempt
+ * to access files or directories in the filesystem it is providing.
+ * (This includes calling stat() on the mount-point, statfs() calls from the 'df' command,
+ * and so on and so forth.) It is worth paying a little attention and being careful about this.
+ *
+ * Enabling multiple threads, by using fuse_loop_mt(), will cause FUSE to make multiple simultaneous
+ * calls into the various callback functions given by your fuse_operations record.
+ *
+ * If you are using multiple threads, you can enjoy all the parallel execution and interactive
+ * response benefits of threads, and you get to enjoy all the benefits of race conditions
+ * and locking bugs, too. Ensure that any code used in the callback funtion of fuse_operations
+ * is also thread-safe.
*
* @param f the FUSE handle
* @return 0 if no error occurred, -1 otherwise
+ *
+ * See also: fuse_loop()
*/
int fuse_loop_mt(struct fuse *f);
diff --git a/include/fuse_common.h b/include/fuse_common.h
index af16203..9fd4bbb 100644
--- a/include/fuse_common.h
+++ b/include/fuse_common.h
@@ -451,8 +451,14 @@ ssize_t fuse_buf_copy(struct fuse_bufvec *dst, struct fuse_bufvec *src,
* Stores session in a global variable. May only be called once per
* process until fuse_remove_signal_handlers() is called.
*
+ * Once either of the POSIX signals arrives, the exit_handler() in fuse_signals.c is called:
+ * \snippet fuse_signals.c doxygen_exit_handler
+ *
* @param se the session to exit
* @return 0 on success, -1 on failure
+ *
+ * See also:
+ * fuse_remove_signal_handlers()
*/
int fuse_set_signal_handlers(struct fuse_session *se);
@@ -463,6 +469,9 @@ int fuse_set_signal_handlers(struct fuse_session *se);
* be called again.
*
* @param se the same session as given in fuse_set_signal_handlers()
+ *
+ * See also:
+ * fuse_set_signal_handlers()
*/
void fuse_remove_signal_handlers(struct fuse_session *se);
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index d46ef86..ada5ce8 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1565,6 +1565,9 @@ int fuse_req_interrupted(fuse_req_t req);
* @param op_size sizeof(struct fuse_lowlevel_ops)
* @param userdata user data
* @return the created session object, or NULL on failure
+ *
+ * Example: See hello_ll.c:
+ * \snippet hello_ll.c doxygen_fuse_lowlevel_usage
*/
struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
const struct fuse_lowlevel_ops *op,
@@ -1707,7 +1710,9 @@ int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf,
void fuse_session_destroy(struct fuse_session *se);
/**
- * Exit a session
+ * Exit a session. This function is invoked by the POSIX signal handlers, when registered using:
+ * * fuse_set_signal_handlers()
+ * * fuse_remove_signal_handlers()
*
* @param se the session
*/
@@ -1737,7 +1742,11 @@ int fuse_session_exited(struct fuse_session *se);
void *fuse_session_data(struct fuse_session *se);
/**
- * Enter a single threaded event loop
+ * Enter a single threaded, blocking event loop.
+ *
+ * Using POSIX signals this event loop can be exited but the session
+ * needs to be configued by issuing:
+ * fuse_set_signal_handlers() first.
*
* @param se the session
* @return 0 on success, -1 on error
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index 82e3001..82e3001 100644..100755
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
diff --git a/lib/fuse_signals.c b/lib/fuse_signals.c
index 88ac39e..cab9951 100644
--- a/lib/fuse_signals.c
+++ b/lib/fuse_signals.c
@@ -14,12 +14,14 @@
static struct fuse_session *fuse_instance;
+//! [doxygen_exit_handler]
static void exit_handler(int sig)
{
(void) sig;
if (fuse_instance)
fuse_session_exit(fuse_instance);
}
+//! [doxygen_exit_handler]
static int set_one_signal_handler(int sig, void (*handler)(int))
{