Subject: Re: kern/25279: NFS read doesn't update atime
To: Manuel Bouyer <bouyer@antioche.lip6.fr>
From: Chuck Silvers <chuq@chuq.com>
List: tech-kern
Date: 07/04/2005 09:58:01
On Wed, Jun 29, 2005 at 11:00:43AM +0200, Manuel Bouyer wrote:
> On Wed, Jun 29, 2005 at 09:43:18AM +0900, YAMAMOTO Takashi wrote:
> > > 
> > > You mean VOP_WRITE ?
> > 
> > no, i meant GOP_WRITE, which starts i/o.
> > ffs currently uses genfs_gop_write for it.
n> 
> Ha yes. Sorry, I didn't know these functions.
> Yes, this works. Here is a new patch. LFS and ext2fs currently untested.

ok, I've thought about all this a bit more.

it seems to me that the goal for coordinating mtime updates with data changes
made via mappings should be to approximate the behaviour of read() / write()
as closely as possible.  for write(), the data change and mtime update are
done atomically, since each write() operation updates both while holding the
same lock.  this means that we do not see any new data before the new mtime,
nor do we see new data after the new mtime.  since changes made via mappings
cannot practically be made atomically with mtime changes, we relax this a
bit to allow multiple changes via mappings to be made without changing the
mtime for each access to the mapping.  however, we would still like to
have the mtime be updated with the first change to the file data and
reasonably soon after the last change to the file data.  this implies
updating mtime both in VOP_GETPAGES() with VM_PROT_WRITE and when we
write back pages dirtied via mappings in VOP_PUTPAGES().  currently the
VOP_GETPAGES() path may not detect the first write access if a pmap-level
mapping allowing write access was previous entered, but we know how to
fix that eventually, and that's not the most serious problem.

however, VOP_PUTPAGES() is used to write back dirty pages that were created
both via write() and via mappings, and we would like to avoid updating mtime
again when flushing dirty pages created by write(), since in that case there
is no question as to whether the mtime was updated in a coherent manner with
the file data.  while it would be possible to track exactly which pages are
dirtied via which mechanism, that would be rather messy.  most applications
modify file data via one interface or the other and don't flip back and forth,
so we'll usually do the right thing if we assume that.  currently we don't
know exactly when a vnode has mappings since we don't keep a count of them,
but we can approximate this by setting a flag in the vnode when a mapping is
created, and clearing this flag in VOP_INACTIVE().  in VOP_PUTPAGES(), we
would update mtime only if this flag is set.  I think that would give us
the desired behaviour in the vast majority of cases.

-Chuck