Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp2127556ybc; Sun, 24 Nov 2019 13:35:38 -0800 (PST) X-Google-Smtp-Source: APXvYqy96exKHTAo4exvt8VThD4AMmNtHbiqAZ/5F2RSyzBU/4Tv+IQGteAiEo8AnAZqGLzWbQeM X-Received: by 2002:a17:906:edd5:: with SMTP id sb21mr33023583ejb.138.1574631338224; Sun, 24 Nov 2019 13:35:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574631338; cv=none; d=google.com; s=arc-20160816; b=mzHSipkbUzaRn3X5PHPIeuK5EV2A1pUCw4Gsu7jLWPa+0WDF6fBUCSN+awyYAVo+v1 m2CHa2hTMpZIocC11IYeujvloBZQpioy55F0bOqnM+kKVj6nYcg4NVxUQUo8kI2UCUJA PaqnTX88agsSuVGJl5X5/ql5T/gz0CNd2CxD+raiyvLRdZjpEzucngJFR6OTC7b+5wj0 4ygTnh7XdZ49f9CYZGeKJaJUUKP6gM/3i+xQTmsuf37q8gMGj4ja2Y3CvyUlfsQHF0gr lPyR0NwqzT9TW3mVMSTwo9hM6fdQCOfIkcn4/JGe1vLJF28L019Z66VWc5c5VoSL8g3X 5KFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=MVBEMSihWfxgGi/ADOuLWZl1cO22F81bwdS5gZmgZj8=; b=B7nVen8zjXwU5/q1KEjYmIx1iJthvBxZu3PEut6RftS6Hz+SrruC2BZTeEZD8qHmJk V4DiFVLsUzUtuy5K+AZBxKYe9cbLt3T491NAilOMrluj9S1Mbva8aufRNq0IBplOCIK6 hSRFI0dGofEP87MMb3qKHGEWDxlcM0MAl3W/qmmweR49I2dBU9hPZH9yJKy2wO7gjZsI nJp2K2yNgCzl9zIaZ7frrkPOh/ZPkxZLly2g4iAyRU4FZgWseCUATu0A+Bmw3Rehe5sh tmDY0OeWAPPh09X5i1nmT3RQ4Af3vyPjESCiC0/KBaNSKnbhOCBiMzuST/yIUtTIou/u fQwQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g2si3156309ejr.279.2019.11.24.13.35.05; Sun, 24 Nov 2019 13:35:38 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-nfs-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726842AbfKXVeV (ORCPT + 99 others); Sun, 24 Nov 2019 16:34:21 -0500 Received: from zeniv.linux.org.uk ([195.92.253.2]:52718 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726840AbfKXVeV (ORCPT ); Sun, 24 Nov 2019 16:34:21 -0500 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92.3 #3 (Red Hat Linux)) id 1iYzWJ-0007zX-VF; Sun, 24 Nov 2019 21:34:16 +0000 Date: Sun, 24 Nov 2019 21:34:15 +0000 From: Al Viro To: Deepa Dinamani Cc: Amir Goldstein , Arnd Bergmann , Jeff Layton , "J . Bruce Fields" , Miklos Szeredi , Linux FS-devel Mailing List , overlayfs , Linux NFS Mailing List , y2038 Mailman List Subject: Re: [PATCH] utimes: Clamp the timestamps in notify_change() Message-ID: <20191124213415.GD4203@ZenIV.linux.org.uk> References: <20191124193145.22945-1-amir73il@gmail.com> <20191124194934.GB4203@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org On Sun, Nov 24, 2019 at 01:13:50PM -0800, Deepa Dinamani wrote: > We also want to replace all uses of timespec64_trunc() with > timestamp_truncate() for all fs cases. > > In that case we have a few more: > > fs/ceph/mds_client.c: req->r_stamp = timespec64_trunc(ts, > mdsc->fsc->sb->s_time_gran); Umm... That comes from ktime_get_coarse_real_ts64(&ts); > fs/cifs/inode.c: fattr->cf_mtime = > timespec64_trunc(fattr->cf_mtime, sb->s_time_gran); ktime_get_real_ts64(&fattr->cf_mtime) here > fs/cifs/inode.c: fattr->cf_atime = > timespec64_trunc(fattr->cf_atime, sb->s_time_gran); ditto > fs/fat/misc.c: inode->i_ctime = > timespec64_trunc(*now, 10000000); I wonder... some are from setattr, some (with NULL passed to fat_truncate_time()) from current_time()... Wouldn't it make more sense to move the truncation into the few callers that really need it (if any)? Quite a few of those are *also* getting the value from current_time(), after all. fat_fill_inode() looks like the only case that doesn't fall into these classes; does it need truncation? BTW, could we *please* do something about fs/inode.c:update_time()? I mean, sure, local variable shadows file-scope function, so it's legitimate C, but this is not IOCCC and having a function called 'update_time' end with return update_time(inode, time, flags); is actively hostile towards casual readers... > fs/fat/misc.c: inode->i_ctime = > fat_timespec64_trunc_2secs(*now); > fs/fat/misc.c: inode->i_mtime = fat_timespec64_trunc_2secs(*now); > fs/ubifs/sb.c: ts = timespec64_trunc(ts, DEFAULT_TIME_GRAN); > > These do not follow from notify_change(), so these might still need > timestamp_truncate() exported. > I will post a cleanup series for timespec64_trunc() also, then we can decide. What I've got right now is commit 6d13412e2b27970810037f7b1b418febcd7013aa Author: Amir Goldstein Date: Sun Nov 24 21:31:45 2019 +0200 utimes: Clamp the timestamps in notify_change() Push clamping timestamps into notify_change(), so in-kernel callers like nfsd and overlayfs will get similar timestamp set behavior as utimes. AV: get rid of clamping in ->setattr() instances; we don't need to bother with that there, with notify_change() doing normalization in all cases now (it already did for implicit case, since current_time() clamps). Suggested-by: Miklos Szeredi Fixes: 42e729b9ddbb ("utimes: Clamp the timestamps before update") Cc: stable@vger.kernel.org # v5.4 Cc: Deepa Dinamani Cc: Jeff Layton Signed-off-by: Amir Goldstein Signed-off-by: Al Viro diff --git a/fs/attr.c b/fs/attr.c index df28035aa23e..b4bbdbd4c8ca 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -183,18 +183,12 @@ void setattr_copy(struct inode *inode, const struct iattr *attr) inode->i_uid = attr->ia_uid; if (ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; - if (ia_valid & ATTR_ATIME) { - inode->i_atime = timestamp_truncate(attr->ia_atime, - inode); - } - if (ia_valid & ATTR_MTIME) { - inode->i_mtime = timestamp_truncate(attr->ia_mtime, - inode); - } - if (ia_valid & ATTR_CTIME) { - inode->i_ctime = timestamp_truncate(attr->ia_ctime, - inode); - } + if (ia_valid & ATTR_ATIME) + inode->i_atime = attr->ia_atime; + if (ia_valid & ATTR_MTIME) + inode->i_mtime = attr->ia_mtime; + if (ia_valid & ATTR_CTIME) + inode->i_ctime = attr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; @@ -268,8 +262,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/configfs/inode.c b/fs/configfs/inode.c index 680aba9c00d5..fd0b5dd68f9e 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -76,14 +76,11 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) if (ia_valid & ATTR_GID) sd_iattr->ia_gid = iattr->ia_gid; if (ia_valid & ATTR_ATIME) - sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime, - inode); + sd_iattr->ia_atime = iattr->ia_atime; if (ia_valid & ATTR_MTIME) - sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime, - inode); + sd_iattr->ia_mtime = iattr->ia_mtime; if (ia_valid & ATTR_CTIME) - sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime, - inode); + sd_iattr->ia_ctime = iattr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = iattr->ia_mode; diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 29bc0a542759..a286564ba2e1 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -751,18 +751,12 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr) inode->i_uid = attr->ia_uid; if (ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; - if (ia_valid & ATTR_ATIME) { - inode->i_atime = timestamp_truncate(attr->ia_atime, - inode); - } - if (ia_valid & ATTR_MTIME) { - inode->i_mtime = timestamp_truncate(attr->ia_mtime, - inode); - } - if (ia_valid & ATTR_CTIME) { - inode->i_ctime = timestamp_truncate(attr->ia_ctime, - inode); - } + if (ia_valid & ATTR_ATIME) + inode->i_atime = attr->ia_atime; + if (ia_valid & ATTR_MTIME) + inode->i_mtime = attr->ia_mtime; + if (ia_valid & ATTR_CTIME) + inode->i_ctime = attr->ia_ctime; if (ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 6c7388430ad3..d4359a1df3d5 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2899,18 +2899,12 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) ia_valid |= ATTR_MTIME | ATTR_CTIME; } } - if (ia_valid & ATTR_ATIME) { - vi->i_atime = timestamp_truncate(attr->ia_atime, - vi); - } - if (ia_valid & ATTR_MTIME) { - vi->i_mtime = timestamp_truncate(attr->ia_mtime, - vi); - } - if (ia_valid & ATTR_CTIME) { - vi->i_ctime = timestamp_truncate(attr->ia_ctime, - vi); - } + if (ia_valid & ATTR_ATIME) + vi->i_atime = attr->ia_atime; + if (ia_valid & ATTR_MTIME) + vi->i_mtime = attr->ia_mtime; + if (ia_valid & ATTR_CTIME) + vi->i_ctime = attr->ia_ctime; mark_inode_dirty(vi); out: return err; diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index cd52585c8f4f..91362079f82a 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1078,18 +1078,12 @@ static void do_attr_changes(struct inode *inode, const struct iattr *attr) inode->i_uid = attr->ia_uid; if (attr->ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; - if (attr->ia_valid & ATTR_ATIME) { - inode->i_atime = timestamp_truncate(attr->ia_atime, - inode); - } - if (attr->ia_valid & ATTR_MTIME) { - inode->i_mtime = timestamp_truncate(attr->ia_mtime, - inode); - } - if (attr->ia_valid & ATTR_CTIME) { - inode->i_ctime = timestamp_truncate(attr->ia_ctime, - inode); - } + if (attr->ia_valid & ATTR_ATIME) + inode->i_atime = attr->ia_atime; + if (attr->ia_valid & ATTR_MTIME) + inode->i_mtime = attr->ia_mtime; + if (attr->ia_valid & ATTR_CTIME) + inode->i_ctime = attr->ia_ctime; if (attr->ia_valid & ATTR_MODE) { umode_t mode = attr->ia_mode; 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; } /*