From ed0cfd8c7ce906b10aac895095545d199eafbcc6 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath Date: Fri, 4 Aug 2017 22:12:36 +0200 Subject: Clarify how the filesystem should handle open/create flags --- include/fuse.h | 59 ++++++++++++++++++++++++++++++++++++++----------- include/fuse_lowlevel.h | 41 ++++++++++++++++++++++++---------- 2 files changed, 75 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/fuse.h b/include/fuse.h index 19fd12c..25457f1 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -380,20 +380,53 @@ struct fuse_operations { */ int (*truncate) (const char *, off_t, struct fuse_file_info *fi); - /** File open operation + /** Open a file + * + * Open flags are available in fi->flags. The following rules + * apply. + * + * - Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be + * filtered out / handled by the kernel. + * + * - Access modes (O_RDONLY, O_WRONLY, O_RDWR) should be used + * by the filesystem to check if the operation is + * permitted. If the ``-o default_permissions`` mount + * option is given, this check is already done by the + * kernel before calling open() and may thus be omitted by + * the filesystem. + * + * - When writeback caching is enabled, the kernel may send + * read requests even for files opened with O_WRONLY. The + * filesystem should be prepared to handle this. + * + * - When writeback caching is disabled, the filesystem is + * expected to properly handle the O_APPEND flag and ensure + * that each write is appending to the end of the file. + * + * - When writeback caching is enabled, the kernel will + * handle O_APPEND. However, unless all changes to the file + * come through the kernel this will not work reliably. The + * filesystem should thus either ignore the O_APPEND flag + * (and let the kernel handle it), or return an error + * (indicating that reliably O_APPEND is not available). + * + * Filesystem may store an arbitrary file handle (pointer, + * index, etc) in fi->fh, and use this in other all other file + * operations (read, write, flush, release, fsync). + * + * Filesystem may also implement stateless file I/O and not store + * anything in fi->fh. + * + * There are also some flags (direct_io, keep_cache) which the + * filesystem may set in fi, to change the way the file is opened. + * See fuse_file_info structure in for more details. + * + * If this request is answered with an error code of ENOSYS + * and FUSE_CAP_NO_OPEN_SUPPORT is set in + * `fuse_conn_info.capable`, this is treated as success and + * future calls to open will also succeed without being send + * to the filesystem process. * - * No creation (O_CREAT, O_EXCL) and by default also no - * truncation (O_TRUNC) flags will be passed to open(). If an - * application specifies O_TRUNC, fuse first calls truncate() - * and then open(). Only if 'atomic_o_trunc' has been - * specified and kernel version is 2.6.24 or later, O_TRUNC is - * passed on to open. - * - * Unless the 'default_permissions' mount option is given, - * open should check if the operation is permitted for the - * given flags. Optionally open may also return an arbitrary - * filehandle in the fuse_file_info structure, which will be - * passed to all file operations. */ int (*open) (const char *, struct fuse_file_info *); diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index 8e036f5..7c0f96f 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -454,8 +454,33 @@ struct fuse_lowlevel_ops { /** * Open a file * - * Open flags are available in fi->flags. Creation (O_CREAT, - * O_EXCL, O_NOCTTY) flags will be filtered out. + * Open flags are available in fi->flags. The following rules + * apply. + * + * - Creation (O_CREAT, O_EXCL, O_NOCTTY) flags will be + * filtered out / handled by the kernel. + * + * - Access modes (O_RDONLY, O_WRONLY, O_RDWR) should be used + * by the filesystem to check if the operation is + * permitted. If the ``-o default_permissions`` mount + * option is given, this check is already done by the + * kernel before calling open() and may thus be omitted by + * the filesystem. + * + * - When writeback caching is enabled, the kernel may send + * read requests even for files opened with O_WRONLY. The + * filesystem should be prepared to handle this. + * + * - When writeback caching is disabled, the filesystem is + * expected to properly handle the O_APPEND flag and ensure + * that each write is appending to the end of the file. + * + * - When writeback caching is enabled, the kernel will + * handle O_APPEND. However, unless all changes to the file + * come through the kernel this will not work reliably. The + * filesystem should thus either ignore the O_APPEND flag + * (and let the kernel handle it), or return an error + * (indicating that reliably O_APPEND is not available). * * Filesystem may store an arbitrary file handle (pointer, * index, etc) in fi->fh, and use this in other all other file @@ -858,16 +883,8 @@ struct fuse_lowlevel_ops { * If the file does not exist, first create it with the specified * mode, and then open it. * - * Open flags (with the exception of O_NOCTTY) are available in - * fi->flags. - * - * Filesystem may store an arbitrary file handle (pointer, index, - * etc) in fi->fh, and use this in other all other file operations - * (read, write, flush, release, fsync). - * - * There are also some flags (direct_io, keep_cache) which the - * filesystem may set in fi, to change the way the file is opened. - * See fuse_file_info structure in for more details. + * See the description of the open handler for more + * information. * * If this method is not implemented or under Linux kernel * versions earlier than 2.6.15, the mknod() and open() methods -- cgit v1.2.3