On Sun, Nov 24, 2019 at 09:31:45PM +0200, Amir Goldstein wrote: > Push clamping timestamps down the call stack into notify_change(), so > in-kernel callers like nfsd and overlayfs will get similar timestamp > set behavior as utimes. So, nfsd has always bypassed timestamp_truncate() and we've never noticed till now? What are the symptoms? (Do timestamps go backwards after cache eviction on filesystems with large time granularity?) Looks like generic/402 has never run in my tests: generic/402 [not run] no kernel support for y2038 sysfs switch --b. > > Suggested-by: Miklos Szeredi <mszeredi@xxxxxxxxxx> > Fixes: 42e729b9ddbb ("utimes: Clamp the timestamps before update") > Cc: stable@xxxxxxxxxxxxxxx # v5.4 > Cc: Deepa Dinamani <deepa.kernel@xxxxxxxxx> > Cc: Jeff Layton <jlayton@xxxxxxxxxx> > Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> > --- > > Arnd, > > This fixes xfstest generic/402 when run with -overlay setup. > Note that running the test requires latest xfstests with: > acb2ba78 - overlay: support timestamp range check > > I had previously posted a fix specific for overlayfs [1], > but Miklos suggested this more generic fix, which should also > serve nfsd and other in-kernel users. > > I tested this change with test generic/402 on ext4/xfs/btrfs > and overlayfs, but not with nfsd. > > Jeff, could you ack this change is good for nfsd as well? > > Thanks, > Amir. > > [1] https://lore.kernel.org/linux-fsdevel/20191111073000.2957-1-amir73il@xxxxxxxxx/ > > fs/attr.c | 5 +++++ > fs/utimes.c | 4 ++-- > 2 files changed, 7 insertions(+), 2 deletions(-) > > diff --git a/fs/attr.c b/fs/attr.c > index df28035aa23e..e8de5e636e66 100644 > --- a/fs/attr.c > +++ b/fs/attr.c > @@ -268,8 +268,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de > attr->ia_ctime = now; > if (!(ia_valid & ATTR_ATIME_SET)) > attr->ia_atime = now; > + else > + attr->ia_atime = timestamp_truncate(attr->ia_atime, inode); > if (!(ia_valid & ATTR_MTIME_SET)) > attr->ia_mtime = now; > + else > + attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode); > + > if (ia_valid & ATTR_KILL_PRIV) { > error = security_inode_need_killpriv(dentry); > if (error < 0) > diff --git a/fs/utimes.c b/fs/utimes.c > index 1ba3f7883870..090739322463 100644 > --- a/fs/utimes.c > +++ b/fs/utimes.c > @@ -36,14 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times) > if (times[0].tv_nsec == UTIME_OMIT) > newattrs.ia_valid &= ~ATTR_ATIME; > else if (times[0].tv_nsec != UTIME_NOW) { > - newattrs.ia_atime = timestamp_truncate(times[0], inode); > + newattrs.ia_atime = times[0]; > newattrs.ia_valid |= ATTR_ATIME_SET; > } > > if (times[1].tv_nsec == UTIME_OMIT) > newattrs.ia_valid &= ~ATTR_MTIME; > else if (times[1].tv_nsec != UTIME_NOW) { > - newattrs.ia_mtime = timestamp_truncate(times[1], inode); > + newattrs.ia_mtime = times[1]; > newattrs.ia_valid |= ATTR_MTIME_SET; > } > /* > -- > 2.17.1