Linux-Fsdevel Archive on
help / color / mirror / Atom feed
From: Krzysztof Rusek <>
To: Miklos Szeredi <>,
Subject: fuse_notify_inval_inode() may be ineffective when getattr request is in progress
Date: Mon, 4 May 2020 13:00:21 +0200	[thread overview]
Message-ID: <> (raw)

[-- Attachment #1: Type: text/plain, Size: 2197 bytes --]


I'm working on a user-space file system implementation utilizing fuse 
kernel module (and libfuse user-space library). This file system 
implementation provides a custom ioctl operation that uses 
fuse_lowlevel_notify_inval_inode() function (which translates to 
fuse_notify_inval_inode() in kernel) to notify the kernel that the file 
was changed by the ioctl. However, under certain circumstances, 
fuse_notify_inval_inode() call is ineffective, resulting in incorrect 
file attributes being cached by the kernel. The problem occurs when 
ioctl() is executed in parallel with getattr().

I noticed this problem on RedHat 7.7 (3.10.0-1062.el7.x86_64), but I 
believe mainline kernel is affected as well.

I think there is a bug in the way fuse_notify_inval_inode() invalidates 
file attributes. If getattr() started before fuse_notify_inval_inode() 
was called, then the attributes returned by user-space process may be 
out of date, and should not be cached. But fuse_notify_inval_inode() 
only clears attribute validity time, which does not prevent getattr() 
result from being cached.

More precisely, this bug occurs in the following scenario:

1. kernel starts handling ioctl
2. file system process receives ioctl request
3. kernel starts handling getattr
4. file system process receives getattr request
5. file system process executes getattr
6. file system process executes ioctl, changing file state
7. file system process invokes fuse_lowlevel_notify_inval_inode(), which 
invalidates file attributes in kernel
8. file system process sends ioctl reply, ioctl handling ends
9. file system process sends getattr reply, attributes are incorrectly 
cached in the kernel

(Note that this scenario assumes that file system implementation is 
multi-threaded, therefore allowing ioctl() and getattr() to be handled 
in parallel.)

I'm attaching an archive with a reproduction test for this problem. The 
archive contains a README file explaining how to compile/run it.

By the way, to avoid a somehow similar race when write() is executed in 
parallel with getattr(), there is a special FUSE_I_SIZE_UNSTABLE bit set 
for the duration of write() operation.

Best regards,
Krzysztof Rusek

[-- Attachment #2: fusebug.tar.gz --]
[-- Type: application/gzip, Size: 2582 bytes --]

             reply	other threads:[~2020-05-04 11:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-04 11:00 Krzysztof Rusek [this message]
2020-05-18 13:08 ` Miklos Szeredi
2020-05-20 12:23   ` Krzysztof Rusek
2020-05-20 12:26     ` Miklos Szeredi

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:

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

  git send-email \ \ \ \ \
    --subject='Re: fuse_notify_inval_inode() may be ineffective when getattr request is in progress' \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).