Linux-Fsdevel Archive on
help / color / mirror / Atom feed
* fuse_notify_inval_inode() may be ineffective when getattr request is in progress
@ 2020-05-04 11:00 Krzysztof Rusek
  2020-05-18 13:08 ` Miklos Szeredi
  0 siblings, 1 reply; 4+ messages in thread
From: Krzysztof Rusek @ 2020-05-04 11:00 UTC (permalink / raw)
  To: Miklos Szeredi, linux-fsdevel

[-- 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 --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-20 12:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-04 11:00 fuse_notify_inval_inode() may be ineffective when getattr request is in progress Krzysztof Rusek
2020-05-18 13:08 ` Miklos Szeredi
2020-05-20 12:23   ` Krzysztof Rusek
2020-05-20 12:26     ` Miklos Szeredi

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).