Discussion:
let FS force FDIRECT
Emmanuel Dreyfus
2014-08-12 09:33:26 UTC
Permalink
Hi

I have hit a FUSE feature that seems to require a bit of kernel hacking to
be supported on NetBSD: At open() time, a FUSE filesystem returns a set
of flags to the kernel, one of them being FOPEN_DIRECT_IO. It tells the
kernel that access to this file must bypass the page cache.

It is used for /proc-like features. For instance, glusterFS has a /.meta
directory with dynamically filled files that tell things about the FS
itself. Since it is dynamically generated, LOOKUP on the file get metadata
with size sets as 0. When we need to read the file, PUFFS does not send
a requesto to the FS since page cache is enabled for the whole filesystem,
and in that case, a READ request beyond end of file is handled within the
kernel.

Supporting direct I/O at PUFFS level is easy: for a file_t, when f_flags
has FDIRECT, vn_read() calls VOP_READ with IO_DIRECT in ioflags.
puffs_vnop_read() can just look at (ioflags & IO_DIRECT) and decide to
bypass the page cache for this given operation.

But the tricky part is that puffs_vnop_open() should be able to set FDIRECT
in file_t's f_flags when the usrland FS replies with the FOPEN_DIRECT_IO.
puffs_vnop_open() does not see the file_t, it sees the struct vnode, hence
it cannot set FDIRECT right now.

A possible solution would be to turn into an (int *) the a_mode in VOP_OPEN(),
and fmode invn_open(), so that ths method implementing OPEN in FS
(here puffs_vnop_open) can change the flags and have the new value
propagated to file_t's f_flags. But that is a heavy change and it modify
the VFS interface.

A less intrusive way is to cheat and just add a VV_IO_DIRECT flag for struct
vnode's v_vflag. puffs_vnoop_open() could set it without any VFS interface
modification, and VOP_READ() could use it to force IO_DIRECT.

The later is cheating because we cannot support the situation where the
filesystem tells us to use direct IO on a file descriptor and not on another
one. But I am not sure it could make sense from a FS point of view.

Any opinion on this?
--
Emmanuel Dreyfus
***@netbsd.org
Emmanuel Dreyfus
2014-08-12 11:48:31 UTC
Permalink
Post by Emmanuel Dreyfus
A possible solution would be to turn into an (int *) the a_mode in VOP_OPEN(),
and fmode invn_open(), so that ths method implementing OPEN in FS
(here puffs_vnop_open) can change the flags and have the new value
propagated to file_t's f_flags. But that is a heavy change and it modify
the VFS interface.
Or I can add ant int *new_a_mode / int *new_fmode as an additionnal argument
to those fonctions. If passed NULL, behavior is unaltered. If passed != NULL,
the upper layer gets the new fmode value from filesystem.

Thoughts?
--
Emmanuel Dreyfus
***@netbsd.org
Emmanuel Dreyfus
2014-08-12 16:52:36 UTC
Permalink
Post by Emmanuel Dreyfus
A less intrusive way is to cheat and just add a VV_IO_DIRECT flag for struct
vnode's v_vflag. puffs_vnoop_open() could set it without any VFS interface
modification, and VOP_READ() could use it to force IO_DIRECT.
The later is cheating because we cannot support the situation where the
filesystem tells us to use direct IO on a file descriptor and not on another
one. But I am not sure it could make sense from a FS point of view.
We can cheat that way and keep the flag in struct puffs_node, leaving
struct vnode untouched. This patch does that:
http://ftp.espci.fr/shadow/manu/iodirect.patch

Questions:

1) Is the feature interesting beyond PUFFS? If not, then the patch above
will probably be fine.

2) Should I bump libpuffs minor in such a situation?
--
Emmanuel Dreyfus
***@netbsd.org
Emmanuel Dreyfus
2014-08-13 03:58:30 UTC
Permalink
Post by Emmanuel Dreyfus
We can cheat that way and keep the flag in struct puffs_node, leaving
http://ftp.espci.fr/shadow/manu/iodirect.patch
Updated patch, which uses a new argument in PUFFS open2 method for flags
from FS. We may want to support some later that do not map to flags in
the mode argument.

http://ftp.espci.fr/shadow/manu/iodirect2.patch

While there, FUSE open has two other open flags returned by FS:

- FOPEN_KEEP_CACHE: do not flush page cache on open. Do we do it
somewhere in the kernel? If not, then I guess the open method should
call puffs_flush_pagecache_node() when that flag is not sent.

- FOPEN_NONSEEKABLE: the FS cannot seek. The seek method in perfused
does nothing anyway, hence I removed it in my patch: it just wasted time
with useless requests from kernel.
--
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
***@netbsd.org
Loading...