diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index c222137..30d72e6 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -479,6 +479,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
 	struct ceph_fs_client *fsc;
 	struct ceph_osd_client *osdc;
 	struct ceph_snap_context *snapc, *oldest;
+	struct timespec ts;
 	loff_t page_off = page_offset(page);
 	loff_t snap_size = -1;
 	long writeback_stat;
@@ -540,11 +541,12 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
 	ceph_readpage_to_fscache(inode, page);
 
 	set_page_writeback(page);
+	ts = vfs_time_to_timespec(inode->i_mtime);
 	err = ceph_osdc_writepages(osdc, ceph_vino(inode),
 				   &ci->i_layout, snapc,
 				   page_off, len,
 				   truncate_seq, truncate_size,
-				   &inode->i_mtime, &page, 1);
+				   &ts, &page, 1);
 	if (err < 0) {
 		dout("writepage setting page/mapping error %d %p\n", err, page);
 		SetPageError(page);
@@ -699,6 +701,7 @@ static int ceph_writepages_start(struct address_space *mapping,
 	int rc = 0;
 	unsigned wsize = 1 << inode->i_blkbits;
 	struct ceph_osd_request *req = NULL;
+	struct timespec ts;
 	int do_sync = 0;
 	loff_t snap_size, i_size;
 	u64 truncate_size;
@@ -978,8 +981,9 @@ get_more_pages:
 		osd_req_op_extent_update(req, 0, len);
 
 		vino = ceph_vino(inode);
+		ts = vfs_time_to_timespec(inode->i_mtime);
 		ceph_osdc_build_request(req, offset, snapc, vino.snap,
-					&inode->i_mtime);
+					&ts);
 
 		rc = ceph_osdc_start_request(&fsc->client->osdc, req, true);
 		BUG_ON(rc);
@@ -1465,6 +1469,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
 	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
 	struct ceph_osd_request *req;
 	struct page *page = NULL;
+	struct timespec ts;
 	u64 len, inline_version;
 	int err = 0;
 	bool from_pagecache = false;
@@ -1528,7 +1533,8 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
 		goto out;
 	}
 
-	ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, &inode->i_mtime);
+	ts = vfs_time_to_timespec(inode->i_mtime);
+	ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, &ts);
 	err = ceph_osdc_start_request(&fsc->client->osdc, req, false);
 	if (!err)
 		err = ceph_osdc_wait_request(&fsc->client->osdc, req);
@@ -1572,7 +1578,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
 			goto out_put;
 	}
 
-	ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, &inode->i_mtime);
+	ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, &ts);
 	err = ceph_osdc_start_request(&fsc->client->osdc, req, false);
 	if (!err)
 		err = ceph_osdc_wait_request(&fsc->client->osdc, req);
@@ -1622,6 +1628,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool)
 	struct ceph_osd_request *rd_req = NULL, *wr_req = NULL;
 	struct rb_node **p, *parent;
 	struct ceph_pool_perm *perm;
+	struct timespec ts;
 	struct page **pages;
 	int err = 0, err2 = 0, have = 0;
 
@@ -1701,12 +1708,13 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool)
 
 	osd_req_op_raw_data_in_pages(rd_req, 0, pages, PAGE_SIZE,
 				     0, false, true);
+	ts = vfs_time_to_timespec(ci->vfs_inode.i_mtime);
 	ceph_osdc_build_request(rd_req, 0, NULL, CEPH_NOSNAP,
-				&ci->vfs_inode.i_mtime);
+				&ts);
 	err = ceph_osdc_start_request(&fsc->client->osdc, rd_req, false);
 
 	ceph_osdc_build_request(wr_req, 0, NULL, CEPH_NOSNAP,
-				&ci->vfs_inode.i_mtime);
+				&ts);
 	err2 = ceph_osdc_start_request(&fsc->client->osdc, wr_req, false);
 
 	if (!err)
diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c
index a351480..789121c 100644
--- a/fs/ceph/cache.c
+++ b/fs/ceph/cache.c
@@ -105,7 +105,7 @@ static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
 	const struct inode* inode = &ci->vfs_inode;
 
 	memset(&aux, 0, sizeof(aux));
-	aux.mtime = inode->i_mtime;
+	aux.mtime = vfs_time_to_timespec(inode->i_mtime);
 	aux.size = i_size_read(inode);
 
 	memcpy(buffer, &aux, sizeof(aux));
@@ -131,7 +131,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
 		return FSCACHE_CHECKAUX_OBSOLETE;
 
 	memset(&aux, 0, sizeof(aux));
-	aux.mtime = inode->i_mtime;
+	aux.mtime = vfs_time_to_timespec(inode->i_mtime);
 	aux.size = i_size_read(inode);
 
 	if (memcmp(data, &aux, sizeof(aux)) != 0)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index cdbf8cf..03b7212 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1178,8 +1178,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
 	ci->i_reported_size = size;
 	max_size = ci->i_wanted_max_size;
 	ci->i_requested_max_size = max_size;
-	mtime = inode->i_mtime;
-	atime = inode->i_atime;
+	mtime = vfs_time_to_timespec(inode->i_mtime);
+	atime = vfs_time_to_timespec(inode->i_atime);
 	time_warp_seq = ci->i_time_warp_seq;
 	uid = inode->i_uid;
 	gid = inode->i_gid;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 9b338ff..0b782c6 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -1497,6 +1497,7 @@ static int ceph_zero_partial_object(struct inode *inode,
 	struct ceph_inode_info *ci = ceph_inode(inode);
 	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
 	struct ceph_osd_request *req;
+	struct timespec ts;
 	int ret = 0;
 	loff_t zero = 0;
 	int op;
@@ -1520,8 +1521,9 @@ static int ceph_zero_partial_object(struct inode *inode,
 		goto out;
 	}
 
+	ts = vfs_time_to_timespec(inode->i_mtime);
 	ceph_osdc_build_request(req, offset, NULL, ceph_vino(inode).snap,
-				&inode->i_mtime);
+				&ts);
 
 	ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
 	if (!ret) {
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 63d0198..7e560bf 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -594,6 +594,7 @@ void ceph_fill_file_time(struct inode *inode, int issued,
 			 struct timespec *mtime, struct timespec *atime)
 {
 	struct ceph_inode_info *ci = ceph_inode(inode);
+	struct timespec ts;
 	int warn = 0;
 
 	if (issued & (CEPH_CAP_FILE_EXCL|
@@ -601,38 +602,42 @@ void ceph_fill_file_time(struct inode *inode, int issued,
 		      CEPH_CAP_FILE_BUFFER|
 		      CEPH_CAP_AUTH_EXCL|
 		      CEPH_CAP_XATTR_EXCL)) {
-		if (timespec_compare(ctime, &inode->i_ctime) > 0) {
+		ts = vfs_time_to_timespec(inode->i_ctime);
+		if (timespec_compare(ctime, &ts) > 0) {
 			dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
-			     inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
+			     ts.tv_sec, ts.tv_nsec,
 			     ctime->tv_sec, ctime->tv_nsec);
-			inode->i_ctime = *ctime;
+			inode->i_ctime = timespec_to_vfs_time(*ctime);
 		}
 		if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
 			/* the MDS did a utimes() */
+			ts = vfs_time_to_timespec(inode->i_mtime);
 			dout("mtime %ld.%09ld -> %ld.%09ld "
 			     "tw %d -> %d\n",
-			     inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
+			     ts.tv_sec, ts.tv_nsec,
 			     mtime->tv_sec, mtime->tv_nsec,
 			     ci->i_time_warp_seq, (int)time_warp_seq);
 
-			inode->i_mtime = *mtime;
-			inode->i_atime = *atime;
+			inode->i_mtime = timespec_to_vfs_time(*mtime);
+			inode->i_atime = timespec_to_vfs_time(*atime);
 			ci->i_time_warp_seq = time_warp_seq;
 		} else if (time_warp_seq == ci->i_time_warp_seq) {
 			/* nobody did utimes(); take the max */
-			if (timespec_compare(mtime, &inode->i_mtime) > 0) {
+			ts = vfs_time_to_timespec(inode->i_mtime);
+			if (timespec_compare(mtime, &ts) > 0) {
 				dout("mtime %ld.%09ld -> %ld.%09ld inc\n",
-				     inode->i_mtime.tv_sec,
-				     inode->i_mtime.tv_nsec,
+				     ts.tv_sec,
+				     ts.tv_nsec,
 				     mtime->tv_sec, mtime->tv_nsec);
-				inode->i_mtime = *mtime;
+				inode->i_mtime = timespec_to_vfs_time(*mtime);
 			}
-			if (timespec_compare(atime, &inode->i_atime) > 0) {
+			ts = vfs_time_to_timespec(inode->i_atime);
+			if (timespec_compare(atime, &ts) > 0) {
 				dout("atime %ld.%09ld -> %ld.%09ld inc\n",
-				     inode->i_atime.tv_sec,
-				     inode->i_atime.tv_nsec,
+				     ts.tv_sec,
+				     ts.tv_nsec,
 				     atime->tv_sec, atime->tv_nsec);
-				inode->i_atime = *atime;
+				inode->i_atime = timespec_to_vfs_time(*atime);
 			}
 		} else if (issued & CEPH_CAP_FILE_EXCL) {
 			/* we did a utimes(); ignore mds values */
@@ -642,9 +647,9 @@ void ceph_fill_file_time(struct inode *inode, int issued,
 	} else {
 		/* we have no write|excl caps; whatever the MDS says is true */
 		if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) >= 0) {
-			inode->i_ctime = *ctime;
-			inode->i_mtime = *mtime;
-			inode->i_atime = *atime;
+			inode->i_ctime = timespec_to_vfs_time(*ctime);
+			inode->i_mtime = timespec_to_vfs_time(*mtime);
+			inode->i_atime = timespec_to_vfs_time(*atime);
 			ci->i_time_warp_seq = time_warp_seq;
 		} else {
 			warn = 1;
@@ -1776,6 +1781,8 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 	struct ceph_mds_request *req;
 	struct ceph_mds_client *mdsc = ceph_sb_to_client(dentry->d_sb)->mdsc;
 	struct ceph_cap_flush *prealloc_cf;
+	struct timespec inode_ts;
+	struct timespec iattr_ts;
 	int issued;
 	int release = 0, dirtied = 0;
 	int mask = 0;
@@ -1862,45 +1869,49 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 		}
 	}
 
+	inode_ts = vfs_time_to_timespec(inode->i_atime);
+	iattr_ts = vfs_time_to_timespec(attr->ia_atime);
 	if (ia_valid & ATTR_ATIME) {
 		dout("setattr %p atime %ld.%ld -> %ld.%ld\n", inode,
-		     inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
-		     attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec);
+		     inode_ts.tv_sec, inode_ts.tv_nsec,
+		     iattr_ts.tv_sec, iattr_ts.tv_nsec);
 		if (issued & CEPH_CAP_FILE_EXCL) {
 			ci->i_time_warp_seq++;
 			inode->i_atime = attr->ia_atime;
 			dirtied |= CEPH_CAP_FILE_EXCL;
 		} else if ((issued & CEPH_CAP_FILE_WR) &&
-			   timespec_compare(&inode->i_atime,
-					    &attr->ia_atime) < 0) {
+			   timespec_compare(&inode_ts,
+					    &iattr_ts) < 0) {
 			inode->i_atime = attr->ia_atime;
 			dirtied |= CEPH_CAP_FILE_WR;
 		} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
-			   !timespec_equal(&inode->i_atime, &attr->ia_atime)) {
+			   !timespec_equal(&inode_ts, &iattr_ts)) {
 			ceph_encode_timespec(&req->r_args.setattr.atime,
-					     &attr->ia_atime);
+					     &iattr_ts);
 			mask |= CEPH_SETATTR_ATIME;
 			release |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
 				CEPH_CAP_FILE_WR;
 		}
 	}
+	inode_ts = vfs_time_to_timespec(inode->i_mtime);
+	iattr_ts = vfs_time_to_timespec(attr->ia_mtime);
 	if (ia_valid & ATTR_MTIME) {
 		dout("setattr %p mtime %ld.%ld -> %ld.%ld\n", inode,
-		     inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
-		     attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec);
+		     inode_ts.tv_sec, inode_ts.tv_nsec,
+		     iattr_ts.tv_sec, iattr_ts.tv_nsec);
 		if (issued & CEPH_CAP_FILE_EXCL) {
 			ci->i_time_warp_seq++;
 			inode->i_mtime = attr->ia_mtime;
 			dirtied |= CEPH_CAP_FILE_EXCL;
 		} else if ((issued & CEPH_CAP_FILE_WR) &&
-			   timespec_compare(&inode->i_mtime,
-					    &attr->ia_mtime) < 0) {
+			   timespec_compare(&inode_ts,
+					    &iattr_ts) < 0) {
 			inode->i_mtime = attr->ia_mtime;
 			dirtied |= CEPH_CAP_FILE_WR;
 		} else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
-			   !timespec_equal(&inode->i_mtime, &attr->ia_mtime)) {
+			   !timespec_equal(&inode_ts, &iattr_ts)) {
 			ceph_encode_timespec(&req->r_args.setattr.mtime,
-					     &attr->ia_mtime);
+					     &iattr_ts);
 			mask |= CEPH_SETATTR_MTIME;
 			release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
 				CEPH_CAP_FILE_WR;
@@ -1929,12 +1940,14 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
 	}
 
 	/* these do nothing */
+	inode_ts = vfs_time_to_timespec(inode->i_ctime);
+	iattr_ts = vfs_time_to_timespec(attr->ia_ctime);
 	if (ia_valid & ATTR_CTIME) {
 		bool only = (ia_valid & (ATTR_SIZE|ATTR_MTIME|ATTR_ATIME|
 					 ATTR_MODE|ATTR_UID|ATTR_GID)) == 0;
 		dout("setattr %p ctime %ld.%ld -> %ld.%ld (%s)\n", inode,
-		     inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
-		     attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
+		     inode_ts.tv_sec, inode_ts.tv_nsec,
+		     iattr_ts.tv_sec, iattr_ts.tv_nsec,
 		     only ? "ctime only" : "ignored");
 		inode->i_ctime = attr->ia_ctime;
 		if (only) {
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 348b22e..01811f9 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2791,6 +2791,7 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
 	struct ceph_inode_info *ci;
 	struct ceph_reconnect_state *recon_state = arg;
 	struct ceph_pagelist *pagelist = recon_state->pagelist;
+	struct timespec ts;
 	char *path;
 	int pathlen, err;
 	u64 pathbase;
@@ -2839,7 +2840,9 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
 		rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
 		rec.v1.issued = cpu_to_le32(cap->issued);
 		rec.v1.size = cpu_to_le64(inode->i_size);
-		ceph_encode_timespec(&rec.v1.mtime, &inode->i_mtime);
+		ts = vfs_time_to_timespec(inode->i_mtime);
+		ceph_encode_timespec(&rec.v1.mtime, &ts);
+		ts = vfs_time_to_timespec(inode->i_atime);
 		ceph_encode_timespec(&rec.v1.atime, &inode->i_atime);
 		rec.v1.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
 		rec.v1.pathbase = cpu_to_le64(pathbase);
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index 4aa7122..aea3344 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -593,9 +593,9 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
 
 	BUG_ON(capsnap->writing);
 	capsnap->size = inode->i_size;
-	capsnap->mtime = inode->i_mtime;
-	capsnap->atime = inode->i_atime;
-	capsnap->ctime = inode->i_ctime;
+	capsnap->mtime = vfs_time_to_timespec(inode->i_mtime);
+	capsnap->atime = vfs_time_to_timespec(inode->i_atime);
+	capsnap->ctime = vfs_time_to_timespec(inode->i_ctime);
 	capsnap->time_warp_seq = ci->i_time_warp_seq;
 	if (capsnap->dirty_pages) {
 		dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu "
