diff --git a/module/zfs/zfs_replay.c b/module/zfs/zfs_replay.c index 54c17543727..b631ba65b96 100644 --- a/module/zfs/zfs_replay.c +++ b/module/zfs/zfs_replay.c @@ -805,6 +805,8 @@ zfs_replay_setattr(zfs_sb_t *zsb, lr_setattr_t *lr, boolean_t byteswap) vap->va_size = lr->lr_size; ZFS_TIME_DECODE(&vap->va_atime, lr->lr_atime); ZFS_TIME_DECODE(&vap->va_mtime, lr->lr_mtime); + gethrestime(&vap->va_ctime); + vap->va_mask |= ATTR_CTIME; /* * Fill in xvattr_t portions if necessary. diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 82016af7504..405b37c1925 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -3001,7 +3001,6 @@ top: aclp = NULL; } - if ((mask & ATTR_ATIME) || zp->z_atime_dirty) { zp->z_atime_dirty = 0; ZFS_TIME_ENCODE(&ip->i_atime, atime); @@ -3011,29 +3010,27 @@ top: if (mask & ATTR_MTIME) { ZFS_TIME_ENCODE(&vap->va_mtime, mtime); + ZTOI(zp)->i_mtime = timespec_trunc(vap->va_mtime, + ZTOI(zp)->i_sb->s_time_gran); + SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, mtime, sizeof (mtime)); } - /* XXX - shouldn't this be done *before* the ATIME/MTIME checks? */ - if (mask & ATTR_SIZE && !(mask & ATTR_MTIME)) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), - NULL, mtime, sizeof (mtime)); + if (mask & ATTR_CTIME) { + ZFS_TIME_ENCODE(&vap->va_ctime, ctime); + ZTOI(zp)->i_ctime = timespec_trunc(vap->va_ctime, + ZTOI(zp)->i_sb->s_time_gran); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, - &ctime, sizeof (ctime)); - zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime); - } else if (mask != 0) { - SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, - &ctime, sizeof (ctime)); - zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime); - if (attrzp) { - SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, - SA_ZPL_CTIME(zsb), NULL, - &ctime, sizeof (ctime)); - zfs_tstamp_update_setup(attrzp, STATE_CHANGED, - mtime, ctime); - } + ctime, sizeof (ctime)); } + + if (attrzp && mask) { + SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, + SA_ZPL_CTIME(zsb), NULL, &ctime, + sizeof (ctime)); + } + /* * Do this after setting timestamps to prevent timestamp * update from toggling bit diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c index 8c75698e588..010f0fd4e21 100644 --- a/module/zfs/zpl_inode.c +++ b/module/zfs/zpl_inode.c @@ -335,7 +335,8 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia) vap->va_ctime = ia->ia_ctime; if (vap->va_mask & ATTR_ATIME) - ip->i_atime = ia->ia_atime; + ip->i_atime = timespec_trunc(ia->ia_atime, + ip->i_sb->s_time_gran); cookie = spl_fstrans_mark(); error = -zfs_setattr(ip, vap, 0, cr);