Bug 203665 - nfs only invalidates directory cache on ctime, not mtime
Summary: nfs only invalidates directory cache on ctime, not mtime
Alias: None
Product: File System
Classification: Unclassified
Component: NFS (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Trond Myklebust
Depends on:
Reported: 2019-05-21 16:55 UTC by Pierre Ossman
Modified: 2019-05-21 19:23 UTC (History)
0 users

See Also:
Kernel Version: git
Tree: Mainline
Regression: No


Description Pierre Ossman 2019-05-21 16:55:48 UTC
AFAICT from man pages and documentation, a NFS client should invalidate its view of a directory if mtime of the directory changes. This makes sense as that attribute should change if a file is removed or added.

However the observed behaviour from the Linux kernel is that it completely ignores changes to mtime. You can observe mtime updating via stat calls from the client, but the client shows stale directory contents. This stale content is also permanent and not subject to any cache timeout.

What the client does look at instead is ctime. This distinction doesn't seem to matter much for Linux servers (all UNIX:y systems?) as both mtime and ctime are updated when a file is added or removed. However other systems do not have this behaviour, e.g. Windows that abuses the ctime for "creation time".

I'm having trouble following the cache system in the code, but from what I can tell nfs_lookup_revalidate_dentry() should decide if a refresh is needed. And it in turn expects nfs_refresh_inode() to make that call. And that seem to involve nfs_inode_attrs_need_update() which has a comment that it only looks at ctime.

This behaviour seems to have been around for ages, so we'll have to work around it in our end anyway. But I figured I'd at least inform you. :)
Comment 1 Trond Myklebust 2019-05-21 17:00:30 UTC
Sorry, but we will not be trying to fix Windows server bugs on the Linux client.
Comment 2 Pierre Ossman 2019-05-21 17:15:08 UTC
I'm confused. Are you're saying I've read the documentation wrong? Or the documentation is incorrect?

I.e. a server MUST update ctime if a file is added or removed and this is a valid assumption by the Linux NFS client?
Comment 3 Trond Myklebust 2019-05-21 18:00:09 UTC
I'm saying that RFC1813 does not allow servers to change the meaning of ctime. That kind of change will have repercussions on all attribute revalidation.

To quote from RFC1813:

   In some cases, a server can support most of the semantics
   described by the protocol but not all. For example, the ctime
   field in the fattr structure gives the time that a file's
   attributes were last modified. Many systems do not keep this
   information. In this case, rather than not support the GETATTR
   operation, a server could simulate it by returning the last
   modified time in place of ctime.  Servers must be careful when
   simulating attribute information because of possible side
   effects on clients.

In this case, if they are replacing the ctime with the birth time, they are not even trying to emulate the expected behaviour. We can't and we won't support that kind of abuse of the protocol.
Comment 4 Pierre Ossman 2019-05-21 19:04:59 UTC
Right, I'm not saying that responding with birth time in ctime is in any way sane. That is not really the issue here.

What I'm concerned about is that using ctime to determine if a directory needs to be re-checked seems off and that it should really be mtime a kernel looks at. RFC1813 doesn't seem to say much about when you can and cannot cache the contents of a directory unfortunately. But given that the files of a directory is it's "data", it seems wrong to look at ctime which would indicate changes in things like ownership of the directory itself. And I could not find any documentation clearly stating that ctime MUST change.

If the Windows server is fixed so that ctime represents the last time the ownership or permissions of the directory was changed, then the Linux server would still be unable to talk to that server. It would need to implement the same semantics as Linux, and I'd really like to be able to point to a source as to why that is. It would be much preferable to "/* Because the Linux kernel doesn't work otherwise */".
Comment 5 Trond Myklebust 2019-05-21 19:23:11 UTC
The reason for choosing the ctime is because that is the basis for most NFSv4 change attributes, and so it allows us to reuse the same code between NFSv2, NFSv3 and NFSv4.

Another issue is that mtime can be set directly by application, and is often reset by backup/restore programs after restoring a file or directory. In those cases we want to detect that the file/directory and its contents may have changed. That means checking the ctime anyway to ensure that mtime+ctime are indeed in sync.

Note You need to log in before you can comment on or make changes to this bug.