Subject: Re: kern/31430: ptyfs isn't getting mtime right
To: None <christos@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: netbsd-bugs
Date: 10/12/2005 22:23:19
Simon Burge wrote:

> Simon Burge wrote:
> 
> > >Number:         31430
> > >Category:       kern
> > >Synopsis:       ptyfs isn't getting mtime right
> 
> I've changed the synopsis of this to
> 
> 	tty's aren't getting mtime right
> 
> as the problem isn't specific to ptyfs - it also affects serial ports
> and older bsd-style ptys.
> 
> The problem also seems to go back at least as far a 1.6.1:
> 
>   way:~ 8> date
>   Sat Oct  1 17:18:01 EST 2005
> 
> and
> 
>   way:~ 11> ls -lT /dev/ttyp[01]
>   crw--w----  1 simonb  tty  5, 0 Oct  1 17:18:13 2005 /dev/ttyp0
>   crw--w----  1 simonb  tty  5, 1 Oct  1 17:18:35 2005 /dev/ttyp1
> 
> but note there the tty mtime is about 12 seconds late, but at least older
> than the other tty used for the ls command.
> 
> Simon.
> --
> Simon Burge                            <simonb@wasabisystems.com>
> NetBSD Support and Service:         http://www.wasabisystems.com/
> 

At least in the ptyfs case, I've worked out that a call to ptyfs_write
sets the "mtime modified" flag, but the mtime itself isn't modified
until ptyfs_itimes is called, usually during a call to ptyfs_getattr.
This explains why the mtime is the same as the next call to (say)
stat(2) after the pty is modified.

The patch below is a result of a discussion off-line with Christos.
The granularity of the mtime doesn't need to be down to the nanosecond
- using the kernel "time" variable (which is updated on each
hardclock call) saves a potentially relatively expensive call to
microtime/nanotime for each write, and is more than accurate enough to
track pty idle times.

For the old-style ptys I suspect the mtime is updated when the inode
will be synced to disk.

Christos - OK to commit the below patch?

Cheers,
Simon.
--
Simon Burge                            <simonb@wasabisystems.com>
NetBSD Support and Service:         http://www.wasabisystems.com/


Index: ptyfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vnops.c,v
retrieving revision 1.9
diff -d -p -u -r1.9 ptyfs_vnops.c
--- ptyfs_vnops.c	12 Sep 2005 16:42:09 -0000	1.9
+++ ptyfs_vnops.c	12 Oct 2005 09:29:43 -0000
@@ -800,11 +800,16 @@ ptyfs_read(void *v)
 		int  a_ioflag;
 		struct ucred *a_cred;
 	} */ *ap = v;
+	struct timespec ts;
 	struct vnode *vp = ap->a_vp;
 	struct ptyfsnode *ptyfs = VTOPTYFS(vp);
 	int error;
 
 	ptyfs->ptyfs_flag |= PTYFS_ACCESS;
+	/* hardclock() resolution is good enough for ptyfs */
+	TIMEVAL_TO_TIMESPEC(&time, &ts);
+	(void)VOP_UPDATE(vp, &ts, &ts, 0);
+
 	switch (ptyfs->ptyfs_type) {
 	case PTYFSpts:
 		VOP_UNLOCK(vp, 0);
@@ -832,11 +837,16 @@ ptyfs_write(void *v)
 		int  a_ioflag;
 		struct ucred *a_cred;
 	} */ *ap = v;
-	int error;
+	struct timespec ts;
 	struct vnode *vp = ap->a_vp;
 	struct ptyfsnode *ptyfs = VTOPTYFS(vp);
+	int error;
 
 	ptyfs->ptyfs_flag |= PTYFS_MODIFY;
+	/* hardclock() resolution is good enough for ptyfs */
+	TIMEVAL_TO_TIMESPEC(&time, &ts);
+	(void)VOP_UPDATE(vp, &ts, &ts, 0);
+
 	switch (ptyfs->ptyfs_type) {
 	case PTYFSpts:
 		VOP_UNLOCK(vp, 0);