Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Mar 2015 13:33:55 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        src-committers@freebsd.org, Jilles Tjoelker <jilles@stack.nl>, Don Lewis <truckman@freebsd.org>, delphij@freebsd.org, svn-src-head@freebsd.org, svn-src-all@freebsd.org
Subject:   Re: svn commit: r280308 - head/sys/fs/devfs
Message-ID:  <20150330103355.GD2379@kib.kiev.ua>
In-Reply-To: <20150330145148.C1660@besplex.bde.org>
References:  <20150322162507.GD2379@kib.kiev.ua> <201503221825.t2MIP7jv096531@gw.catspoiler.org> <20150329175137.GD95224@stack.nl> <20150329184238.GB2379@kib.kiev.ua> <20150330145148.C1660@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Mar 30, 2015 at 03:14:10PM +1100, Bruce Evans wrote:
> File timestamps use CLOCK_REALTIME, so they are supposed to go backwards
> sometimes.  More importantly, if the time is set to a future time (by
> utimes(), etc., not due to a clock step), this prevents it being correted.
> I think you only want to do a null update if tv_nsec is nonzero due to a
> previous setting with vfs_timestamp(), and the new second hasn't arrived
> yet.  Something like:
> 
>  		if (tsp->tv_sec != ts) ...
> 
> If '<', then as above.  If '>', it means a correction by >= 1 second
> (strictly greater if tv_nsec != 0).  The initial value tv_nsec is
> irrelevant in both cases.

Below is the updated patch.  I also added a comment to devfs_timestamp(),
please reformulate it to your liking.

diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 941f92c..552ddd2 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -84,7 +84,27 @@ SYSCTL_DECL(_vfs_devfs);
 
 static int devfs_dotimes;
 SYSCTL_INT(_vfs_devfs, OID_AUTO, dotimes, CTLFLAG_RW,
-        &devfs_dotimes, 0, "Update timestamps on DEVFS");
+    &devfs_dotimes, 0, "Update timestamps on DEVFS with default precision");
+
+/*
+ * Update devfs node timestamp.  Note that updates are unlocked and
+ * stat(2) could see partially updated times.
+ */
+static void
+devfs_timestamp(struct timespec *tsp)
+{
+	time_t ts;
+
+	if (devfs_dotimes) {
+		vfs_timestamp(tsp);
+	} else {
+		ts = time_second;
+		if (tsp->tv_sec != ts) {
+			tsp->tv_sec = ts;
+			tsp->tv_nsec = 0;
+		}
+	}
+}
 
 static int
 devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp,
@@ -1228,9 +1248,8 @@ devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred,
 
 	foffset_lock_uio(fp, uio, flags | FOF_NOLOCK);
 	error = dsw->d_read(dev, uio, ioflag);
-	if (devfs_dotimes &&
-	    (uio->uio_resid != resid || (error == 0 && resid != 0)))
-		vfs_timestamp(&dev->si_atime);
+	if (uio->uio_resid != resid || (error == 0 && resid != 0))
+		devfs_timestamp(&dev->si_atime);
 	td->td_fpop = fpop;
 	dev_relthread(dev, ref);
 
@@ -1708,9 +1727,8 @@ devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
 	resid = uio->uio_resid;
 
 	error = dsw->d_write(dev, uio, ioflag);
-	if (devfs_dotimes &&
-	    (uio->uio_resid != resid || (error == 0 && resid != 0))) {
-		vfs_timestamp(&dev->si_ctime);
+	if (uio->uio_resid != resid || (error == 0 && resid != 0)) {
+		devfs_timestamp(&dev->si_ctime);
 		dev->si_mtime = dev->si_ctime;
 	}
 	td->td_fpop = fpop;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150330103355.GD2379>