You skimmed over some stuff, like the pathname lookup componentThe patch basically does:Would you describe the situation that would cause the kernel to
go into an infinite loop, please?
do {
...
error = inode->i_op->foo()
...
} while (error == ESTALE);
What is the guarantee, that ->foo() will not always return ESTALE?
contained in the first set of dots...
I can't guarantee that ->foo() won't always return ESTALE.
That said, the loop is not unbreakable. At least for NFS, a signal
to the process will interrupt the loop because the error returned
will change from ESTALE to EINTR.
In FUSE interrupts are sent to userspace, and the filesystem decides
what to do with them. So it is entirely possible and valid for a
filesystem to ignore an interrupt. If an operation was non-blocking
(such as one returning an error), then there would in fact be no
purpose in checking interrupts.
So while sending a signal might reliably work in NFS to break out of
the loop, it does not necessarily work for other filesystems, and fuse
may not be the only one affected.
Also up till now, returning ESTALE in a fuse filesystem was a
perfectly valid thing to do. This patch changes the behavior of that
rather drastically. There might be installed systems that rely on
current behavior, and we want to avoid breaking those on a kernel
upgrade.
A few solutions come to mind, perhaps the best is to introduce a
kernel internal errno value (ERETRYSTALE), that forces the relevant
system calls to be retried.
NFS could transform ESTALE errors to ERETRYSTALE and get the desired
behavior, while other filesystems would not be affected.