Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: Luis Henriques <luis@igalia.com>
To: Amir Goldstein <amir73il@gmail.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	 Chen Linxuan <me@black-desk.cn>,
	Jonathan Corbet <corbet@lwn.net>,
	 Shuah Khan <skhan@linuxfoundation.org>,
	 fuse-devel@lists.linux.dev, linux-kernel@vger.kernel.org,
	 linux-kselftest@vger.kernel.org,
	 Matt Harvey <mharvey@jumptrading.com>,
	 kernel-dev@igalia.com
Subject: Re: [RFC PATCH v2 1/8] Documentation: fuse: add document on caches being used by FUSE
Date: Tue, 18 Aug 2026 16:51:44 +0100	[thread overview]
Message-ID: <87mruje8a7.fsf@wotan.olymp> (raw)
In-Reply-To: <CAOQ4uxjsx-Atq3tGsUeakGNZYLVHayVXPne1E6gM0J9tZp+f6g@mail.gmail.com> (Amir Goldstein's message of "Tue, 18 Aug 2026 14:40:15 +0200")

On Tue, Aug 18 2026, Amir Goldstein wrote:

> On Mon, Aug 17, 2026 at 4:11 PM Luis Henriques <luis@igalia.com> wrote:
>>
>> This new file aims at documenting the caches that are used by FUSE.  At
>> the moment only symlink, attributes, ACLs and readdir caches are described.
>>
>> Signed-off-by: Luis Henriques <luis@igalia.com>
>> ---
>>  .../filesystems/fuse/fuse-caches.rst          | 142 ++++++++++++++++++
>>  1 file changed, 142 insertions(+)
>>  create mode 100644 Documentation/filesystems/fuse/fuse-caches.rst
>>
>> diff --git a/Documentation/filesystems/fuse/fuse-caches.rst b/Documentation/filesystems/fuse/fuse-caches.rst
>> new file mode 100644
>> index 000000000000..071febf45d00
>> --- /dev/null
>> +++ b/Documentation/filesystems/fuse/fuse-caches.rst
>> @@ -0,0 +1,142 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +===========
>> +FUSE Caches
>> +===========
>> +
>> +Introduction
>> +============
>> +
>> +This document summarises the different types of caches that are used in FUSE.
>> +For each cache type, it attempts to document the rules that are followed to
>> +insert, validate and invalidate data into the cache.
>> +
>> +symlink caching
>> +===============
>> +
>> +Whenever there's a link resolution request, the VFS will call into
>> +``fuse_get_link()`` which will then send a ``FUSE_READLINK`` request to the
>> +user-space FUSE server. However, the server can ask the kernel to cache all
>> +links resolutions by setting the ``FUSE_CACHE_SYMLINKS`` flag during the
>> +``FUSE_INIT`` negotiation.
>> +
>> +If this flag is set, FUSE will immediately call into the VFS
>> +``__page_get_link()`` from the ``->get_link()`` inode operation. The first time
>> +this is done for a specific link, it will end-up sending the ``FUSE_READLINK``
>> +to user-space but the link contents will then be added into page-cache. The next
>> +time the link needs to be resolved, it will use the link content that is already
>> +cached, and will only fallback into sending the request to use-space if the
>> +folio isn't up-to-date.
>> +
>> +Attributes caching
>> +==================
>> +
>> +Attributes obtained from user-space, for example when an inode is first
>> +looked-up, are cached in the kernel. However, these attributes have a timeout
>> +associated and once expired they are invalidated.
>> +
>> +Thus, the ``FUSE_GETATTR`` operation will be sent to user-space only if the
>> +attributes aren't yet available, the attributes aren't valid (timeout), or if
>> +there is an explicit request for doing so (for example, by using the
>> +``AT_STATX_FORCE_SYNC`` flag in ``statx``). This may happen in the following
>> +situations:
>
> "This may happen" what may happen? I don't see it referring to anything.

Yeah, that sentence doesn't really make a lot of sense.  I'll rephrase.

>> +
>> +#. An explicit request from VFS to get the attributes for an inode (through the
>> +   ``->getattr()`` callback).
>> +#. When an ``->llseek()`` is requested to FUSE with a type of request
>> +   (``whence``):
>> +
>> +   -  ``SEEK_{HOLE,DATA}`` and the user-space doesn't implement the
>> +      ``FUSE_LSEEK`` operation (it has returned ``ENOSYS``), or
>> +   -  ``SEEK_END``
>> +
>> +#. When doing a buffered read past EOF or automatic page cache invalidation mode
>> +   is enabled (``FUSE_AUTO_INVAL_DATA``).
>> +#. When doing a buffered write with write-back cache enabled
>> +   (``FUSE_CAP_WRITEBACK_CACHE``).
>
> This list is incomplete and strange. it has post EOF write for
> writeback which is the exception
> and leaves out every non writeback write.

This list was meant to list the scenarios where the FUSE_GETATTR is sent
(the "this may happen" above).  But I'll review the list again.

> If you composed this list yourself I highly recommend an LLM for this task
> if you used LLM I suggest a stronger model.
>
> Generally speaking, I find that today's robots are much better at writing these
> sorts of docs than I am - as long as I sit at the helm and guide them
> about where to expand on and where to keep it concise.

Thank you for the suggestion (I did not use an LLM btw).  In fact, do you
think this document is really useful, given that everyone will be running
an LLM anyway?  (I've been asking this question myself...)

>> +
>> +ACL caching
>> +===========
>> +
>> +FUSE has allowed the usage of POSIX ACLs for a long time as they could be set
>> +and accessed simply as extended attributes. However, it was only with the
>> +addition of the ``FUSE_POSIX_ACL`` flag that ACLs started to be fully supported.
>> +Without this flag, ACLs can still be set, but the VFS won't use them for
>> +performing permission checks - that would be the user-space server's
>> +responsibility.
>> +
>> +Also, without setting ``FUSE_POSIX_ACL``, ACLs will not be cached by the kernel.
>> +In this case, new inodes ``i_acl`` and ``i_default_acl`` fields will be set to
>> +``ACL_DONT_CACHE``.
>> +
>> +On the other hand, if ``FUSE_POSIX_ACL`` is set during ``FUSE_INIT``, when an
>> +ACL is accessed the VFS layer will first check if it's already cached. If it is
>> +not, FUSE ``->get_acl`` operation is called, which will eventually send a
>> +user-space request. Future accesses to this inode ACL will then use the cached
>> +data.
>> +
>> +Setting an ACL in an inode, however, won't cache it immediately. It will send
>> +user-space a request with the new ACL, and the FUSE server may perform some
>> +modifications before storing it.
>
> Do not encourage this by documenting it please.
> It reinforces that this was by design, rather than an oversight which
> we don't know.

Eh! OK, I'll stop that sentence after the comma :-)

>> +
>> +On the other hand, ACLs will be removed for the cache in the following
>> +situations:
>> +
>> +-  When setting an ACL in an inode and the user-space server has set the
>> +   ``FUSE_POSIX_ACL`` flag, all previously cached ACLs for this inode will be
>> +   invalidated.
>> +-  When invalidating an inode through the ``FUSE_NOTIFY_INVAL_INODE`` operation.
>> +-  When ``->d_revalidate()`` is called for a dentry that requires a lookup (e.g.
>> +   it has expired) and that lookup operation is successful.
>> +-  When the VFS needs to check access rights for an inode (by calling
>> +   ``->permission()``), attributes may need to be refreshed. If that happens,
>> +   any cached ACLs for that inode will be invalidated.
>> +-  After setting an inode attribute (i.e. operation ``FUSE_SETATTR`` is sent to
>> +   user-space), the user-space server may have also updated the ACLs, so any
>> +   cached ACLs for this inode are also invalidated.
>> +-  While processing ``FUSE_READDIRPLUS`` and a new dentry is added (unless this
>> +   dentry is already being looked up (``DCACHE_PAR_LOOKUP``))
>> +-  In general, when there is the need to sent a ``FUSE_STATX`` or
>> +   ``FUSE_GETATTR`` to user-space (e.g. because the attributes have expired).
>> +   This may happen in the following cases:
>> +
>> +   -  When doing an ``->llseek()`` on a file with ``SEEK_END``, ``SEEK_HOLE`` or
>> +      ``SEEK_DATA``.
>> +   -  When the ``FUSE_AUTO_INVAL_DATA`` flag is set at ``INIT`` time (to
>> +      automatically invalidate cached pages), and a buffered read
>> +      (``->read_iter()``) past EOF is done on a non-passthrough file.
>> +   -  When the ``FUSE_WRITEBACK_CACHE`` flag is set at ``INIT`` time, and a
>> +      buffered write (``->write_iter()``) past EOF is done on a non-passthrough
>> +      file.
>> +   -  When the ``FUSE_AUTO_INVAL_DATA`` flag is set at ``INIT`` time and the VFS
>> +      needs to read a directory contents (``->iterate_shared()``) for a
>> +      directory that is allowed to be cached.
>
> No reason to repeat the reasons for attr cache invalidation that were
> just listed above
>
>> +
>> +readdir caching
>> +===============
>> +
>> +When opening a directory for doing a readdir, a ``FUSE_OPENDIR`` will be sent
>> +and the user-space server will be responsible for setting the open flags related
>> +with caching, namely ``FOPEN_KEEP_CACHE`` and ``FOPEN_CACHE_DIR``.
>> +
>> +If neither flags are set by the user-space FUSE server, then every ``readdir``
>> +will result in a ``FUSE_READDIR`` (or ``FUSE_READDIRPLUS``) request being sent.
>> +If ``FOPEN_CACHE_DIR`` is set by the server, then the result of a ``readdir``
>> +will be cached by the kernel and reused. However, if ``FOPEN_KEEP_CACHE`` isn't
>> +also set, the cache will be invalidated next time the directory is open.
>
> Confusing.
> FOPEN_KEEP_CACHE is about keeping the cache on THIS open not on
> some NEXT open.

Right, that's true.  I just wanted to emphasise that the invalidation
doesn't happen on a close, but on the next open.  But I'll rephrase,
thanks.

Cheers,
-- 
Luís

  reply	other threads:[~2026-08-18 15:51 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 14:11 [RFC PATCH v2 0/8] fuse: caches documentation and testing Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 1/8] Documentation: fuse: add document on caches being used by FUSE Luis Henriques
2026-08-18 12:40   ` Amir Goldstein
2026-08-18 15:51     ` Luis Henriques [this message]
2026-08-18 19:57       ` Amir Goldstein
2026-08-17 14:11 ` [RFC PATCH v2 2/8] selftests/fuse: convert fusectl test to fuse3 Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 3/8] selftests/fuse: check that fusectlfs is mounted Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 4/8] selftests/fuse: add fuse symlink caching test Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 5/8] selftests/fuse: factor-out test fixture setup/teardown Luis Henriques
2026-08-18 13:09   ` Amir Goldstein
2026-08-18 15:51     ` Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 6/8] selftests/fuse: use dynamically allocated memory to store ACLs Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 7/8] selftests/fuse: add some extra ACL caching tests Luis Henriques
2026-08-17 14:11 ` [RFC PATCH v2 8/8] selftests/fuse: add fuse readdir caching test Luis Henriques
2026-08-18 13:13 ` [RFC PATCH v2 0/8] fuse: caches documentation and testing Amir Goldstein
2026-08-18 15:52   ` Luis Henriques

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87mruje8a7.fsf@wotan.olymp \
    --to=luis@igalia.com \
    --cc=amir73il@gmail.com \
    --cc=corbet@lwn.net \
    --cc=fuse-devel@lists.linux.dev \
    --cc=kernel-dev@igalia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=me@black-desk.cn \
    --cc=mharvey@jumptrading.com \
    --cc=miklos@szeredi.hu \
    --cc=skhan@linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox