Skip to content

Commit

Permalink
fuse: add a new fuse init flag to relax restrictions in no cache mode
Browse files Browse the repository at this point in the history
FOPEN_DIRECT_IO is usually set by fuse daemon to indicate need of strong
coherency, e.g. network filesystems.  Thus shared mmap is disabled since it
leverages page cache and may write to it, which may cause inconsistence.

But FOPEN_DIRECT_IO can be used not for coherency but to reduce memory
footprint as well, e.g. reduce guest memory usage with virtiofs.
Therefore, add a new fuse init flag FUSE_DIRECT_IO_RELAX to relax
restrictions in that mode, currently, it allows shared mmap.  One thing to
note is to make sure it doesn't break coherency in your use case.

Signed-off-by: Hao Xu <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
  • Loading branch information
Hao Xu authored and Miklos Szeredi committed Aug 16, 2023
1 parent 80e4f25 commit e78662e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 4 deletions.
7 changes: 5 additions & 2 deletions fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2451,14 +2451,17 @@ static const struct vm_operations_struct fuse_file_vm_ops = {
static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
{
struct fuse_file *ff = file->private_data;
struct fuse_conn *fc = ff->fm->fc;

/* DAX mmap is superior to direct_io mmap */
if (FUSE_IS_DAX(file_inode(file)))
return fuse_dax_mmap(file, vma);

if (ff->open_flags & FOPEN_DIRECT_IO) {
/* Can't provide the coherency needed for MAP_SHARED */
if (vma->vm_flags & VM_MAYSHARE)
/* Can't provide the coherency needed for MAP_SHARED
* if FUSE_DIRECT_IO_RELAX isn't set.
*/
if ((vma->vm_flags & VM_MAYSHARE) && !fc->direct_io_relax)
return -ENODEV;

invalidate_inode_pages2(file->f_mapping);
Expand Down
3 changes: 3 additions & 0 deletions fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,9 @@ struct fuse_conn {
/* Is tmpfile not implemented by fs? */
unsigned int no_tmpfile:1;

/* relax restrictions in FOPEN_DIRECT_IO mode */
unsigned int direct_io_relax:1;

/** The number of requests waiting for completion */
atomic_t num_waiting;

Expand Down
4 changes: 3 additions & 1 deletion fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,8 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
fc->init_security = 1;
if (flags & FUSE_CREATE_SUPP_GROUP)
fc->create_supp_group = 1;
if (flags & FUSE_DIRECT_IO_RELAX)
fc->direct_io_relax = 1;
} else {
ra_pages = fc->max_read / PAGE_SIZE;
fc->no_lock = 1;
Expand Down Expand Up @@ -1258,7 +1260,7 @@ void fuse_send_init(struct fuse_mount *fm)
FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT | FUSE_INIT_EXT |
FUSE_SECURITY_CTX | FUSE_CREATE_SUPP_GROUP |
FUSE_HAS_EXPIRE_ONLY;
FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_RELAX;
#ifdef CONFIG_FUSE_DAX
if (fm->fc->dax)
flags |= FUSE_MAP_ALIGNMENT;
Expand Down
8 changes: 7 additions & 1 deletion include/uapi/linux/fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@
* - add FUSE_EXT_GROUPS
* - add FUSE_CREATE_SUPP_GROUP
* - add FUSE_HAS_EXPIRE_ONLY
*
* 7.39
* - add FUSE_DIRECT_IO_RELAX
*/

#ifndef _LINUX_FUSE_H
Expand Down Expand Up @@ -242,7 +245,7 @@
#define FUSE_KERNEL_VERSION 7

/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 38
#define FUSE_KERNEL_MINOR_VERSION 39

/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
Expand Down Expand Up @@ -371,6 +374,8 @@ struct fuse_file_lock {
* FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir,
* symlink and mknod (single group that matches parent)
* FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
* FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now
* allow shared mmap
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
Expand Down Expand Up @@ -409,6 +414,7 @@ struct fuse_file_lock {
#define FUSE_HAS_INODE_DAX (1ULL << 33)
#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
#define FUSE_HAS_EXPIRE_ONLY (1ULL << 35)
#define FUSE_DIRECT_IO_RELAX (1ULL << 36)

/**
* CUSE INIT request/reply flags
Expand Down

0 comments on commit e78662e

Please sign in to comment.