- added a doxygen main page

- 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
This commit is contained in:
Joachim Schiele 2013-06-20 19:18:18 +02:00
parent 18c59ab489
commit ea7227db43
20 changed files with 327 additions and 24 deletions

8
doc/Doxyfile Normal file → Executable file
View File

@ -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

0
doc/how-fuse-works Normal file → Executable file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

92
doc/mainpage.dox Executable file
View File

@ -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.
*/

15
example/cusexmp.c Normal file → Executable file
View File

@ -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>

15
example/fioc.c Normal file → Executable file
View File

@ -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>

9
example/fioc.h Normal file → Executable file
View File

@ -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>

17
example/fioclient.c Normal file → Executable file
View File

@ -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>

15
example/fsel.c Normal file → Executable file
View File

@ -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>

15
example/fselclient.c Normal file → Executable file
View File

@ -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>

16
example/fusexmp.c Normal file → Executable file
View File

@ -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

15
example/fusexmp_fh.c Normal file → Executable file
View File

@ -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

31
example/hello.c Normal file → Executable file
View File

@ -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);

41
example/hello_ll.c Normal file → Executable file
View File

@ -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]

15
example/null.c Normal file → Executable file
View File

@ -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>

View 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);

View 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);

View 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

0
lib/fuse_loop_mt.c Normal file → Executable file
View File

View File

@ -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))
{