[Bug 270749] [FUSEFS] File close() failures relating to attempted atime update
Date: Mon, 10 Apr 2023 23:30:08 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=270749
Bug ID: 270749
Summary: [FUSEFS] File close() failures relating to attempted
atime update
Product: Base System
Version: CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Only Me
Priority: ---
Component: kern
Assignee: bugs@FreeBSD.org
Reporter: jamie@catflap.org
Attachment #241405 text/plain
mime type:
Created attachment 241405
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=241405&action=edit
patch to check whether we have permissions to update atime
There is a bug in fusefs, discovered by ThomasWaldmann@github relating to
closing files on fusefs filesystems.
See: https://github.com/borgbackup/borg/issues/6871
I tracked it down to:
title: fusefs: update atime on reads when using cached attributes
commit: 0bade34633f997c22f5e4e0931df0d534f560a38
author Alan Somers <asomers@FreeBSD.org> 2021-11-29 01:53:31 +0000
committer Alan Somers <asomers@FreeBSD.org> 2021-12-14 22:15:53 +0000
link:
https://cgit.freebsd.org/src/commit/sys/fs/fuse?h=stable/13&id=0bade34633f997c22f5e4e0931df0d534f560a38
The problem only started after that commit - I've tested current (as of today)
and the issue still exists there.
This is my take of what is going on:
Basically, it appears that on a fusefs mounted filesystem, a file close fails
when fuse tries to update the "atime" of a file that it doesn't have
write-access to.
It doesn't matter if the filesystem is mounted read-only - the effect is the
same.
For example, if a file is opened and read, and then closed, all subsequent
closes to that file fail until the filesystem is remounted. - Even closes for
opens that don't themselves update atime fail - presumably because fuse still
has this metadata pending.
The following test demonstrates this. "file-close-check" is a simple c program
that does an fopen/fclose then another fopen/fclose, then fopen/fread 100
bytes/fclose, followed by a final fopen/fclose
These are the results. On the remote system, "/tmp/test[12]" are just small
text files, one owned by me, one not:
4 -rw-r--r-- 1 jamie wheel - 1,626 10 Apr 19:58 test1
4 -rw-r--r-- 1 root wheel - 1,626 10 Apr 18:56 test2
root@catwalk:/tmp # mkdir xx
root@catwalk:/tmp # sshfs jamie@catflap.org:/tmp xx
root@catwalk:/tmp # file-close-check xx/test?
xx/test1 | open: ok, close: ok | open: ok, close: ok | open: ok, read: 100
bytes, close: ok | open: ok, close: ok
xx/test2 | open: ok, close: ok | open: ok, close: ok | open: ok, read: 100
bytes, close: Permission denied | open: ok, close: Permission denied
Then run the same command again:
root@catwalk:/tmp # file-close-check xx/test?
xx/test1 | open: ok, close: ok | open: ok, close: ok | open: ok, read: 100
bytes, close: ok | open: ok, close: ok
xx/test2 | open: ok, close: Permission denied | open: ok, close: Permission
denied | open: ok, read: 100 bytes, close: Permission denied | open: ok, close:
Permission denied
From what I can see, in file "sys/fs/fuse/fuse_vnops.c", it does indeed check
if the data flush succeeded, and if so, and there has been an atime update, it
then tries to set that:
err = fuse_flush(vp, cred, pid, fflag);
if (err == 0 && (fvdat->flag & FN_ATIMECHANGE)) {
struct vattr vap;
VATTR_NULL(&vap);
vap.va_atime = fvdat->cached_attrs.va_atime;
err = fuse_internal_setattr(vp, &vap, td, NULL);
}
However, if there is no data to write, the flush succeeds even if there is no
write access to the file, causing the fuse_internal_setattr to then fail.
The attached patch "fixes" the problem, by adding the "checkparam" code to this
section too, but I don't know if it's the right fix, or if it breaks what the
commit does, so someone with more fusefs experience needs to check it.
Cheers, Jamie
--
You are receiving this mail because:
You are the assignee for the bug.