utimes: Clamp the timestamps in notify_change()
authorAmir Goldstein <amir73il@gmail.com>
Sun, 24 Nov 2019 19:31:45 +0000 (21:31 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 9 Dec 2019 00:10:50 +0000 (19:10 -0500)
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 <mszeredi@redhat.com>
Fixes: 42e729b9ddbb ("utimes: Clamp the timestamps before update")
Cc: stable@vger.kernel.org # v5.4
Cc: Deepa Dinamani <deepa.kernel@gmail.com>
Cc: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/attr.c
fs/configfs/inode.c
fs/f2fs/file.c
fs/ntfs/inode.c
fs/ubifs/file.c
fs/utimes.c

index df28035..b4bbdbd 100644 (file)
--- 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)
index 680aba9..fd0b5dd 100644 (file)
@@ -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;
 
index 85af112..13aef5f 100644 (file)
@@ -754,18 +754,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;
 
index 6c73884..d4359a1 100644 (file)
@@ -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;
index cd52585..9136207 100644 (file)
@@ -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;
 
index c952b6b..1d17ce9 100644 (file)
@@ -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;
                }
                /*