- added a doxygen main page
authorJoachim Schiele <js@lastlog.de>
Thu, 20 Jun 2013 17:18:18 +0000 (19:18 +0200)
committerJoachim Schiele <js@lastlog.de>
Thu, 20 Jun 2013 17:18:18 +0000 (19:18 +0200)
- modified all examples to be included in doxygen
- modified the API documentation to have more details
- added the 490px_FUSE_structure.svg.png (c) wikipedia

20 files changed:
doc/Doxyfile [changed mode: 0644->0755]
doc/how-fuse-works [changed mode: 0644->0755]
doc/images/490px-FUSE_structure.svg.png [new file with mode: 0644]
doc/mainpage.dox [new file with mode: 0755]
example/cusexmp.c [changed mode: 0644->0755]
example/fioc.c [changed mode: 0644->0755]
example/fioc.h [changed mode: 0644->0755]
example/fioclient.c [changed mode: 0644->0755]
example/fsel.c [changed mode: 0644->0755]
example/fselclient.c [changed mode: 0644->0755]
example/fusexmp.c [changed mode: 0644->0755]
example/fusexmp_fh.c [changed mode: 0644->0755]
example/hello.c [changed mode: 0644->0755]
example/hello_ll.c [changed mode: 0644->0755]
example/null.c [changed mode: 0644->0755]
include/fuse.h
include/fuse_common.h
include/fuse_lowlevel.h
lib/fuse_loop_mt.c [changed mode: 0644->0755]
lib/fuse_signals.c

old mode 100644 (file)
new mode 100755 (executable)
index 3926aaf..16ce23a
@@ -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 
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/doc/images/490px-FUSE_structure.svg.png b/doc/images/490px-FUSE_structure.svg.png
new file mode 100644 (file)
index 0000000..a4a9731
Binary files /dev/null and b/doc/images/490px-FUSE_structure.svg.png differ
diff --git a/doc/mainpage.dox b/doc/mainpage.dox
new file mode 100755 (executable)
index 0000000..9202207
--- /dev/null
@@ -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.
+*/
old mode 100644 (file)
new mode 100755 (executable)
index b69f97c..a02818c
@@ -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>
old mode 100644 (file)
new mode 100755 (executable)
index 849bd5d..cfb18ae
@@ -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>
old mode 100644 (file)
new mode 100755 (executable)
index ec1a39d..c9bf358
@@ -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>
old mode 100644 (file)
new mode 100755 (executable)
index 5f05525..9718622
@@ -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>
old mode 100644 (file)
new mode 100755 (executable)
index bddc1aa..3c52033
@@ -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>
old mode 100644 (file)
new mode 100755 (executable)
index 7c4b837..2e2e571
@@ -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>
old mode 100644 (file)
new mode 100755 (executable)
index 42a8134..73e9898
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index eea6b9b..e538b49
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index b31fbe5..c8b4a48
@@ -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);
old mode 100644 (file)
new mode 100755 (executable)
index baf41bc..687c6f1
@@ -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]
old mode 100644 (file)
new mode 100755 (executable)
index 4e2bb8f..6952333
@@ -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>
index 793862e7e6c3dc04719fee80de88cf4ad0ad817d..c7647ce02127c82dc4c1ae48d47b568871fdbef0 100644 (file)
@@ -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);
 
index af16203dff34b60374f8d178bdfc37517ca689ef..9fd4bbb09011b738f4b177b81a0fa3cbff385bcb 100644 (file)
@@ -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);
 
index d46ef867477631599fd1f97c038a1817bc1d992d..ada5ce820ca3675ebec1c02556a847b55318b6b8 100644 (file)
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index 88ac39e187e019b463f962533225721b089ddd19..cab99516b1808a6caf647adfd9150723d23d818a 100644 (file)
 
 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))
 {