Skip to content

Commit e78662e

Browse files
Hao XuMiklos Szeredi
authored andcommitted
fuse: add a new fuse init flag to relax restrictions in no cache mode
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 <howeyxu@tencent.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent 80e4f25 commit e78662e

File tree

4 files changed

+18
-4
lines changed

4 files changed

+18
-4
lines changed

fs/fuse/file.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2451,14 +2451,17 @@ static const struct vm_operations_struct fuse_file_vm_ops = {
24512451
static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
24522452
{
24532453
struct fuse_file *ff = file->private_data;
2454+
struct fuse_conn *fc = ff->fm->fc;
24542455

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

24592460
if (ff->open_flags & FOPEN_DIRECT_IO) {
2460-
/* Can't provide the coherency needed for MAP_SHARED */
2461-
if (vma->vm_flags & VM_MAYSHARE)
2461+
/* Can't provide the coherency needed for MAP_SHARED
2462+
* if FUSE_DIRECT_IO_RELAX isn't set.
2463+
*/
2464+
if ((vma->vm_flags & VM_MAYSHARE) && !fc->direct_io_relax)
24622465
return -ENODEV;
24632466

24642467
invalidate_inode_pages2(file->f_mapping);

fs/fuse/fuse_i.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,9 @@ struct fuse_conn {
792792
/* Is tmpfile not implemented by fs? */
793793
unsigned int no_tmpfile:1;
794794

795+
/* relax restrictions in FOPEN_DIRECT_IO mode */
796+
unsigned int direct_io_relax:1;
797+
795798
/** The number of requests waiting for completion */
796799
atomic_t num_waiting;
797800

fs/fuse/inode.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,8 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
12121212
fc->init_security = 1;
12131213
if (flags & FUSE_CREATE_SUPP_GROUP)
12141214
fc->create_supp_group = 1;
1215+
if (flags & FUSE_DIRECT_IO_RELAX)
1216+
fc->direct_io_relax = 1;
12151217
} else {
12161218
ra_pages = fc->max_read / PAGE_SIZE;
12171219
fc->no_lock = 1;
@@ -1258,7 +1260,7 @@ void fuse_send_init(struct fuse_mount *fm)
12581260
FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
12591261
FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_EXT | FUSE_INIT_EXT |
12601262
FUSE_SECURITY_CTX | FUSE_CREATE_SUPP_GROUP |
1261-
FUSE_HAS_EXPIRE_ONLY;
1263+
FUSE_HAS_EXPIRE_ONLY | FUSE_DIRECT_IO_RELAX;
12621264
#ifdef CONFIG_FUSE_DAX
12631265
if (fm->fc->dax)
12641266
flags |= FUSE_MAP_ALIGNMENT;

include/uapi/linux/fuse.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@
207207
* - add FUSE_EXT_GROUPS
208208
* - add FUSE_CREATE_SUPP_GROUP
209209
* - add FUSE_HAS_EXPIRE_ONLY
210+
*
211+
* 7.39
212+
* - add FUSE_DIRECT_IO_RELAX
210213
*/
211214

212215
#ifndef _LINUX_FUSE_H
@@ -242,7 +245,7 @@
242245
#define FUSE_KERNEL_VERSION 7
243246

244247
/** Minor version number of this interface */
245-
#define FUSE_KERNEL_MINOR_VERSION 38
248+
#define FUSE_KERNEL_MINOR_VERSION 39
246249

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

413419
/**
414420
* CUSE INIT request/reply flags

0 commit comments

Comments
 (0)