diff --git a/fs/attr.c b/fs/attr.c
index 6530ced..4156239 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -148,14 +148,14 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
 	if (ia_valid & ATTR_GID)
 		inode->i_gid = attr->ia_gid;
 	if (ia_valid & ATTR_ATIME)
-		inode->i_atime = timespec_trunc(attr->ia_atime,
-						inode->i_sb->s_time_gran);
+		VFS_INODE_SET_XTIME(i_atime, inode,
+			fs_time_trunc(attr->ia_atime, inode->i_sb));
 	if (ia_valid & ATTR_MTIME)
-		inode->i_mtime = timespec_trunc(attr->ia_mtime,
-						inode->i_sb->s_time_gran);
+		VFS_INODE_SET_XTIME(i_mtime, inode,
+			fs_time_trunc(attr->ia_mtime, inode->i_sb));
 	if (ia_valid & ATTR_CTIME)
-		inode->i_ctime = timespec_trunc(attr->ia_ctime,
-						inode->i_sb->s_time_gran);
+		VFS_INODE_SET_XTIME(i_ctime, inode,
+			fs_time_trunc(attr->ia_ctime, inode->i_sb));
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 
@@ -192,7 +192,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
 	struct inode *inode = dentry->d_inode;
 	umode_t mode = inode->i_mode;
 	int error;
-	struct timespec now;
+	struct inode_timespec now;
 	unsigned int ia_valid = attr->ia_valid;
 
 	WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
@@ -210,7 +210,6 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
 	}
 
 	now = current_fs_time(inode->i_sb);
-
 	attr->ia_ctime = now;
 	if (!(ia_valid & ATTR_ATIME_SET))
 		attr->ia_atime = now;
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 103f5d7..3c51e22 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -169,11 +169,17 @@ static const struct inode_operations bad_inode_ops =
  
 void make_bad_inode(struct inode *inode)
 {
+	struct inode_timespec now;
+
 	remove_inode_hash(inode);
 
 	inode->i_mode = S_IFREG;
-	inode->i_atime = inode->i_mtime = inode->i_ctime =
-		current_fs_time(inode->i_sb);
+
+	now = current_fs_time(inode->i_sb);
+
+	VFS_INODE_SET_XTIME(i_atime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, inode, now);
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
 	inode->i_op = &bad_inode_ops;	
 	inode->i_fop = &bad_file_ops;	
 }
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 78f005f..4fd4437 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -562,12 +562,15 @@ static void entry_status(Node *e, char *page)
 static struct inode *bm_get_inode(struct super_block *sb, int mode)
 {
 	struct inode *inode = new_inode(sb);
+	struct inode_timespec now;
 
 	if (inode) {
 		inode->i_ino = get_next_ino();
 		inode->i_mode = mode;
-		inode->i_atime = inode->i_mtime = inode->i_ctime =
-			current_fs_time(inode->i_sb);
+		now = current_fs_time(inode->i_sb);
+		VFS_INODE_SET_XTIME(i_atime, inode, now);
+		VFS_INODE_SET_XTIME(i_mtime, inode, now);
+		VFS_INODE_SET_XTIME(i_ctime, inode, now);
 	}
 	return inode;
 }
diff --git a/fs/inode.c b/fs/inode.c
index 4c8f719..d3d64dc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1532,27 +1532,36 @@ EXPORT_SYMBOL(bmap);
  * passed since the last atime update.
  */
 static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
-			     struct timespec now)
+			     struct inode_timespec now)
 {
 
+	struct inode_timespec ctime;
+	struct inode_timespec mtime;
+	struct inode_timespec atime;
+
 	if (!(mnt->mnt_flags & MNT_RELATIME))
 		return 1;
+
+	atime = VFS_INODE_GET_XTIME(i_atime, inode);
+	ctime = VFS_INODE_GET_XTIME(i_ctime, inode);
+	mtime = VFS_INODE_GET_XTIME(i_mtime, inode);
+
 	/*
 	 * Is mtime younger than atime? If yes, update atime:
 	 */
-	if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
+	if (inode_timespec_compare(&mtime, &atime) >= 0)
 		return 1;
 	/*
 	 * Is ctime younger than atime? If yes, update atime:
 	 */
-	if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
+	if (inode_timespec_compare(&ctime, &atime) >= 0)
 		return 1;
 
 	/*
 	 * Is the previous atime value older than a day? If yes,
 	 * update atime:
 	 */
-	if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
+	if ((long)(now.tv_sec - atime.tv_sec) >= 24*60*60)
 		return 1;
 	/*
 	 * Good, we can skip the atime update:
@@ -1560,18 +1569,19 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
 	return 0;
 }
 
-int generic_update_time(struct inode *inode, struct timespec *time, int flags)
+int generic_update_time(struct inode *inode, struct inode_timespec *time,
+			int flags)
 {
 	int iflags = I_DIRTY_TIME;
 
 	if (flags & S_ATIME)
-		inode->i_atime = *time;
+		VFS_INODE_SET_XTIME(i_atime, inode, *time);
 	if (flags & S_VERSION)
 		inode_inc_iversion(inode);
 	if (flags & S_CTIME)
-		inode->i_ctime = *time;
+		VFS_INODE_SET_XTIME(i_ctime, inode, *time);
 	if (flags & S_MTIME)
-		inode->i_mtime = *time;
+		VFS_INODE_SET_XTIME(i_mtime, inode, *time);
 
 	if (!(inode->i_sb->s_flags & MS_LAZYTIME) || (flags & S_VERSION))
 		iflags |= I_DIRTY_SYNC;
@@ -1584,9 +1594,10 @@ EXPORT_SYMBOL(generic_update_time);
  * This does the actual work of updating an inodes time or version.  Must have
  * had called mnt_want_write() before calling this.
  */
-static int update_time(struct inode *inode, struct timespec *time, int flags)
+static int update_time(struct inode *inode, struct inode_timespec *time,
+		       int flags)
 {
-	int (*update_time)(struct inode *, struct timespec *, int);
+	int (*update_time)(struct inode *, struct inode_timespec *, int);
 
 	update_time = inode->i_op->update_time ? inode->i_op->update_time :
 		generic_update_time;
@@ -1606,7 +1617,8 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
 bool atime_needs_update(const struct path *path, struct inode *inode)
 {
 	struct vfsmount *mnt = path->mnt;
-	struct timespec now;
+	struct inode_timespec now;
+	struct inode_timespec atime;
 
 	if (inode->i_flags & S_NOATIME)
 		return false;
@@ -1621,11 +1633,11 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
 		return false;
 
 	now = current_fs_time(inode->i_sb);
-
 	if (!relatime_need_update(mnt, inode, now))
 		return false;
 
-	if (timespec_equal(&inode->i_atime, &now))
+	atime = VFS_INODE_GET_XTIME(i_atime, inode);
+	if (inode_timespec_equal(&atime, &now))
 		return false;
 
 	return true;
@@ -1635,7 +1647,7 @@ void touch_atime(const struct path *path)
 {
 	struct vfsmount *mnt = path->mnt;
 	struct inode *inode = d_inode(path->dentry);
-	struct timespec now;
+	struct inode_timespec now;
 
 	if (!atime_needs_update(path, inode))
 		return;
@@ -1770,7 +1782,10 @@ EXPORT_SYMBOL(file_remove_privs);
 int file_update_time(struct file *file)
 {
 	struct inode *inode = file_inode(file);
-	struct timespec now;
+	struct inode_timespec now;
+	struct inode_timespec mtime;
+	struct inode_timespec ctime;
+
 	int sync_it = 0;
 	int ret;
 
@@ -1779,10 +1794,14 @@ int file_update_time(struct file *file)
 		return 0;
 
 	now = current_fs_time(inode->i_sb);
-	if (!timespec_equal(&inode->i_mtime, &now))
+
+	mtime = VFS_INODE_GET_XTIME(i_mtime, inode);
+	ctime = VFS_INODE_GET_XTIME(i_ctime, inode);
+
+	if (!inode_timespec_equal(&mtime, &now))
 		sync_it = S_MTIME;
 
-	if (!timespec_equal(&inode->i_ctime, &now))
+	if (!inode_timespec_equal(&ctime, &now))
 		sync_it |= S_CTIME;
 
 	if (IS_I_VERSION(inode))
diff --git a/fs/libfs.c b/fs/libfs.c
index 4fa2002..5a0c7c2 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -216,6 +216,7 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
 	struct dentry *dentry;
 	struct inode *root;
 	struct qstr d_name = QSTR_INIT(name, strlen(name));
+	struct inode_timespec now;
 
 	s = sget(fs_type, NULL, set_anon_super, MS_NOUSER, NULL);
 	if (IS_ERR(s))
@@ -240,7 +241,11 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name,
 	 */
 	root->i_ino = 1;
 	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
-	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
+	now = current_fs_time(s);
+	VFS_INODE_SET_XTIME(i_atime, root, now);
+	VFS_INODE_SET_XTIME(i_ctime, root, now);
+	VFS_INODE_SET_XTIME(i_mtime, root, now);
+
 	dentry = __d_alloc(s, &d_name);
 	if (!dentry) {
 		iput(root);
@@ -269,8 +274,11 @@ EXPORT_SYMBOL(simple_open);
 int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = d_inode(old_dentry);
+	struct inode_timespec now = current_fs_time(inode->i_sb);
 
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, dir, now);
+	VFS_INODE_SET_XTIME(i_ctime, dir, now);
 	inc_nlink(inode);
 	ihold(inode);
 	dget(dentry);
@@ -303,8 +311,11 @@ EXPORT_SYMBOL(simple_empty);
 int simple_unlink(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = d_inode(dentry);
+	struct inode_timespec now = current_fs_time(inode->i_sb);
 
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, dir, now);
+	VFS_INODE_SET_XTIME(i_ctime, dir, now);
 	drop_nlink(inode);
 	dput(dentry);
 	return 0;
@@ -328,6 +339,7 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
 {
 	struct inode *inode = d_inode(old_dentry);
 	int they_are_dirs = d_is_dir(old_dentry);
+	struct inode_timespec now;
 
 	if (!simple_empty(new_dentry))
 		return -ENOTEMPTY;
@@ -343,8 +355,13 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
 		inc_nlink(new_dir);
 	}
 
-	old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime =
-		new_dir->i_mtime = inode->i_ctime = CURRENT_TIME;
+	now = current_fs_time(inode->i_sb);
+
+	VFS_INODE_SET_XTIME(i_ctime, old_dir, now);
+	VFS_INODE_SET_XTIME(i_mtime, old_dir, now);
+	VFS_INODE_SET_XTIME(i_ctime, new_dir, now);
+	VFS_INODE_SET_XTIME(i_mtime, new_dir, now);
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
 
 	return 0;
 }
@@ -478,6 +495,7 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
 	struct inode *inode;
 	struct dentry *root;
 	struct dentry *dentry;
+	struct inode_timespec now;
 	int i;
 
 	s->s_blocksize = PAGE_CACHE_SIZE;
@@ -497,7 +515,10 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
 	 */
 	inode->i_ino = 1;
 	inode->i_mode = S_IFDIR | 0755;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	now = current_fs_time(inode->i_sb);
+	VFS_INODE_SET_XTIME(i_atime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, inode, now);
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
 	inode->i_op = &simple_dir_inode_operations;
 	inode->i_fop = &simple_dir_operations;
 	set_nlink(inode, 2);
@@ -523,7 +544,10 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
 			goto out;
 		}
 		inode->i_mode = S_IFREG | files->mode;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		now = current_fs_time(inode->i_sb);
+		VFS_INODE_SET_XTIME(i_atime, inode, now);
+		VFS_INODE_SET_XTIME(i_mtime, inode, now);
+		VFS_INODE_SET_XTIME(i_ctime, inode, now);
 		inode->i_fop = files->ops;
 		inode->i_ino = i;
 		d_add(dentry, inode);
@@ -1056,6 +1080,7 @@ struct inode *alloc_anon_inode(struct super_block *s)
 		.set_page_dirty = anon_set_page_dirty,
 	};
 	struct inode *inode = new_inode_pseudo(s);
+	struct inode_timespec now;
 
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
@@ -1074,7 +1099,11 @@ struct inode *alloc_anon_inode(struct super_block *s)
 	inode->i_uid = current_fsuid();
 	inode->i_gid = current_fsgid();
 	inode->i_flags |= S_PRIVATE;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	now = current_fs_time(s);
+	VFS_INODE_SET_XTIME(i_atime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, inode, now);
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
+
 	return inode;
 }
 EXPORT_SYMBOL(alloc_anon_inode);
diff --git a/fs/locks.c b/fs/locks.c
index 15e2b60..2b818eb 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1491,7 +1491,7 @@ EXPORT_SYMBOL(__break_lease);
  * exclusive leases.  The justification is that if someone has an
  * exclusive lease, then they could be modifying it.
  */
-void lease_get_mtime(struct inode *inode, struct timespec *time)
+void lease_get_mtime(struct inode *inode, struct inode_timespec *time)
 {
 	bool has_lease = false;
 	struct file_lock_context *ctx;
@@ -1510,9 +1510,8 @@ void lease_get_mtime(struct inode *inode, struct timespec *time)
 	if (has_lease)
 		*time = current_fs_time(inode->i_sb);
 	else
-		*time = inode->i_mtime;
+		*time = VFS_INODE_GET_XTIME(i_mtime, inode);
 }
-
 EXPORT_SYMBOL(lease_get_mtime);
 
 /**
diff --git a/fs/nsfs.c b/fs/nsfs.c
index 8f20d60..a079fc9 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -51,6 +51,7 @@ void *ns_get_path(struct path *path, struct task_struct *task,
 	struct qstr qname = { .name = "", };
 	struct dentry *dentry;
 	struct inode *inode;
+	struct inode_timespec now;
 	struct ns_common *ns;
 	unsigned long d;
 
@@ -82,7 +83,10 @@ slow:
 		return ERR_PTR(-ENOMEM);
 	}
 	inode->i_ino = ns->inum;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	now = current_fs_time(mnt->mnt_sb);
+	VFS_INODE_SET_XTIME(i_atime, inode, now);
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, inode, now);
 	inode->i_flags |= S_IMMUTABLE;
 	inode->i_mode = S_IFREG | S_IRUGO;
 	inode->i_fop = &ns_file_operations;
diff --git a/fs/pipe.c b/fs/pipe.c
index 42cf8dd..5d414a3 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -637,6 +637,7 @@ static struct inode * get_pipe_inode(void)
 {
 	struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
 	struct pipe_inode_info *pipe;
+	struct inode_timespec now;
 
 	if (!inode)
 		goto fail_inode;
@@ -662,7 +663,10 @@ static struct inode * get_pipe_inode(void)
 	inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
 	inode->i_uid = current_fsuid();
 	inode->i_gid = current_fsgid();
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	now = current_fs_time(pipe_mnt->mnt_sb);
+	VFS_INODE_SET_XTIME(i_atime, inode, now);
+	VFS_INODE_SET_XTIME(i_ctime, inode, now);
+	VFS_INODE_SET_XTIME(i_mtime, inode, now);
 
 	return inode;
 
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 711dd51..0ac55c9 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -859,7 +859,7 @@ int simple_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 			acl = NULL;
 	}
 
-	inode->i_ctime = CURRENT_TIME;
+	VFS_INODE_SET_XTIME(i_ctime, inode, current_fs_time(inode->i_sb));
 	set_cached_acl(inode, type, acl);
 	return 0;
 }
diff --git a/fs/stack.c b/fs/stack.c
index a54e33e..812bbbb 100644
--- a/fs/stack.c
+++ b/fs/stack.c
@@ -66,9 +66,9 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src)
 	dest->i_uid = src->i_uid;
 	dest->i_gid = src->i_gid;
 	dest->i_rdev = src->i_rdev;
-	dest->i_atime = src->i_atime;
-	dest->i_mtime = src->i_mtime;
-	dest->i_ctime = src->i_ctime;
+	VFS_INODE_SET_XTIME(i_atime, dest, VFS_INODE_GET_XTIME(i_atime, src));
+	VFS_INODE_SET_XTIME(i_mtime, dest, VFS_INODE_GET_XTIME(i_mtime, src));
+	VFS_INODE_SET_XTIME(i_ctime, dest, VFS_INODE_GET_XTIME(i_ctime, src));
 	dest->i_blkbits = src->i_blkbits;
 	dest->i_flags = src->i_flags;
 	set_nlink(dest, src->i_nlink);
diff --git a/fs/stat.c b/fs/stat.c
index bc045c7..c448313 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -28,9 +28,9 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
 	stat->gid = inode->i_gid;
 	stat->rdev = inode->i_rdev;
 	stat->size = i_size_read(inode);
-	stat->atime = inode->i_atime;
-	stat->mtime = inode->i_mtime;
-	stat->ctime = inode->i_ctime;
+	stat->atime = VFS_INODE_GET_XTIME(i_atime, inode);
+	stat->mtime = VFS_INODE_GET_XTIME(i_mtime, inode);
+	stat->ctime = VFS_INODE_GET_XTIME(i_ctime, inode);
 	stat->blksize = (1 << inode->i_blkbits);
 	stat->blocks = inode->i_blocks;
 }
diff --git a/fs/utimes.c b/fs/utimes.c
index aa138d6..c23c8e6 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -48,11 +48,12 @@ static bool nsec_valid(long nsec)
 	return nsec >= 0 && nsec <= 999999999;
 }
 
-static int utimes_common(struct path *path, struct timespec *times)
+static int utimes_common(struct path *path, struct inode_timespec *times)
 {
 	int error;
 	struct iattr newattrs;
 	struct inode *inode = path->dentry->d_inode;
+	struct super_block *sb = inode->i_sb;
 	struct inode *delegated_inode = NULL;
 
 	error = mnt_want_write(path->mnt);
@@ -133,7 +134,8 @@ out:
  * must be owner or have write permission.
  * Else, update from *times, must be owner or super user.
  */
-long do_utimes(int dfd, const char __user *filename, struct timespec *times,
+long do_utimes(int dfd, const char __user *filename,
+	       struct inode_timespec *times,
 	       int flags)
 {
 	int error = -EINVAL;
diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h
index da317c7..2d2bb50 100644
--- a/include/linux/fs_stack.h
+++ b/include/linux/fs_stack.h
@@ -15,15 +15,16 @@ extern void fsstack_copy_inode_size(struct inode *dst, struct inode *src);
 static inline void fsstack_copy_attr_atime(struct inode *dest,
 					   const struct inode *src)
 {
-	dest->i_atime = src->i_atime;
+	VFS_INODE_SET_XTIME(i_atime, dest, VFS_INODE_GET_XTIME(i_atime, src));
 }
 
 static inline void fsstack_copy_attr_times(struct inode *dest,
 					   const struct inode *src)
 {
-	dest->i_atime = src->i_atime;
-	dest->i_mtime = src->i_mtime;
-	dest->i_ctime = src->i_ctime;
+	VFS_INODE_SET_XTIME(i_atime, dest, VFS_INODE_GET_XTIME(i_atime, src));
+	VFS_INODE_SET_XTIME(i_mtime, dest, VFS_INODE_GET_XTIME(i_mtime, src));
+	VFS_INODE_SET_XTIME(i_ctime, dest, VFS_INODE_GET_XTIME(i_ctime, src));
+
 }
 
 #endif /* _LINUX_FS_STACK_H */
