libfuse has a different usage of filehandles for files and directories.
A directory filehandle is valid only for directory operations such
as OPENDIR, READDIR, RELEASEDIR, FSYNCDIR. Change of src/lib/libperfuse/ops.c
1.85-1.86 made sure filehandles of directories were only sent for that
operations.
However, the status of lock operations GETLK, SETLK, SETLKW was overlooked.
The only FUSE filesystem I found using locks is GlusterFS, and it needs
directory filehandles to be provided on lock operations, otherwise locking
crashes the filesystem. Hence this change brings back filehandles for
lock operations on directories.
libfuse does not use filehandle the same way for directories and other
objects. As a result, filehandles obtained by OPENDIR should not be
sent on non-directory related operations like READ/WRITE/GETATTR...
While there, fix the lookup count sent to the FORGET operation, which
led to leaked nodes.
The PUFFS reclaim operation had a race condition with lookups: we could
be asked to lookup a node, then to reclaim it before lookup completion.
At lookup completion, we would then create a leaked node.
Enter the PUFFS reclaim2 operation, which features a nlookup argument.
That let us count how many lookups are pending and avoid the above
described scenario. It also makes the codes simplier.
When dealing with high I/O throughput, we could run out of buffer
space if the filesystem was not consuming requests fast enough.
Here we slightly raise the buffer size, and we make it tunable
through the PERFUSE_BUFSIZE environment variable so that we can
cope with higher requirement later.
While there, document PERFUSE_OPTIONS environment variable.
Some filesystems do not provide inode numbers through readdir (FUSE mounts
without -o use_ino). We therefore have to lookup each directory entry to
get the missing numbers.
dot and double-dot are exceptions, as we already know the values. Moreover,
the lookup code does not expect to get requests for dot and will abort
perfused(8) when it gets some. In order to fix that, we just check for
dot and double-dot special case and use the known values instead of sending
a lookup.
FUSE filesystems do not expect to get metadata updates for [amc]time
and size, they updates the value on their own after operations.
The PUFFS PUFFS_KFLAG_NOFLUSH_META option prevents regular metadata cache
flushes to the filesystem , and libperfuse uses it to match Linux FUSE
behavior.
While there, fix a bug in SETATTR: do not update kernel metadata cache
from SETATTR reply when the request is asynchronous, as we do not have
the reply yet.
FUSE filesystems assume that SETATTR with atime is the result of utiimes()
being called. As a result, atime and mtime will be updated. This happens
with MooseFS and glusterFS. atime is supposed to be updated by the
filesystem itself when it gets read operations.
We fix the problem in SETATTR operations by
1) do not create a mtime update when we have an atime update (and vice
versa), just fill the fields to avoid the filesystem restting the
missing field to Epoch, but do not pretend we want to update it.
2) If the change is limited to atime, iscard it, as updates should be
done by READ operations
3) Kernel part of PUFFS has been fixed to make sure reads on empty file
are sent to the filesystem:
http://mail-index.netbsd.org/source-changes/2015/01/13/msg062364.html
Thanks to Tom Ivar Helbekkmo for reporting this issue.
- access denied is EPERM and not EACCES
- access to file owned by someone else in a sticy-bit directory should
be allowed for the sticy-bit directory owner
- setting sticky-bit on a non directory should produce EFTYPE
- implement PATHCONF method as much as we can.
to implement FUSE's OPEN_IO_DIRECT, by which the filesystem tells the kernel
that read/write to the file should bypass the page cache.
Remove a warning about read beyond EOF which will now normally appear when
page cache is bypassed.
able to fetch inode number. We perfom an addtional lookup
on each file to get it.
In that case, do not lookup .. from root, as it breaks
out of the filesystem and hits NULL pointers.
1) with recent FUSE, when lookup returns a null ino, it means ENOENT
2) odd corner case that caused a bug on dd if=test of=test conv=notrunc
This caused the file to be open first ro, then rw. A logic bug in
perfuse_node_open caused it to skip the second operation, whereas
it should open for writing, and store the write FH without touching
the read FH.
parent, keeping them active, and allowing to lookup .. without sending
a request to the filesystem.
Enable the featuure for perfused, as this is how FUSE works.