[Bug 254452] [fusefs] [devel/gvfs]: gvfsd-fuse needs FUSE_CAP_ATOMIC_O_TRUNC from fuse

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Mar 25 02:25:54 UTC 2021


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=254452

--- Comment #4 from Alan Somers <asomers at FreeBSD.org> ---
Unfortunately, it wouldn't be a small patch.  It would be huge, and would
require changes to every other file system.  Here's the problem in a nutshell:

On SunOS and BSD-based operating systems:
- Processes have file descriptors.  File descriptors have a many-to-one*
relationship with "struct file" inside of the kernel.  The current seek offset
and open flags are fields of "struct file", and every "struct file" is owned by
one process.
- "struct file" has a many-to-one relationship with vnodes.  Each file on disk
is associated with at most one vnode.  vnodes are the basic data structure of
the VFS (virtual file system).
- The entry points to a file system are the VOP (VFS operations) functions. 
They take vnodes as arguments, not "struct file".
- So file systems have no concept of file descriptors or seek offsets. 
Basically the read and write functions resemble preadv and pwritev, specifying
the offset of each operation.  The VFS itself takes care of managing a "struct
file"'s seek position.  Also as a consequence, 

In Linux, though I'm a little bit hazier,
- file descriptors also map to a "struct file", which owns the seek offset.
- there is no VFS.
- the entry points to a file system are the file_operation's, which have a
"struct file" argument.  So each file system is responsible for managing every
file's seek offset.

So you can see why FreeBSD can't pass O_APPEND on to the FUSE server.  But it's
even worse than that!  Even in Linux, if the writeback cache is enabled and the
write is coming from cache, there's no way to know which file descriptor is
associated with the write.  So the fuse module must guess.  You can see where
this is going.

But here's the part you care about: Suppose a process opens a file with
O_APPEND.  The fusefs module can, in fact, see that flag during VOP_OPEN.  But
suppose the same process also opens the file a second time, this time without
O_APPEND.  When a VOP_WRITE comes along, the fusefs module can't tell if the
write is for the file descriptor that used O_APPEND or the one that didn't.  

Without knowing very much about gvfs's internals, a simple solution might be to
ignore O_TRUNC and O_APPEND at open time, but to treat every write as an
implicit truncation.  The FUSE_WRITE operation will contain the file offset
anyway.

* It's _usually_ one-to-one, but dup() can make it many-to-one.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-gnome mailing list