@@ -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)
@@ -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)
@@ -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;
@@ -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) {
@@ -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) {
@@ -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);
@@ -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 "
This is in preparation for changing VFS inode timestamps to use 64 bit time. The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time functions to access inode times. Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com> --- fs/ceph/addr.c | 20 +++++++++----- fs/ceph/cache.c | 4 +-- fs/ceph/caps.c | 4 +-- fs/ceph/file.c | 4 ++- fs/ceph/inode.c | 75 ++++++++++++++++++++++++++++++---------------------- fs/ceph/mds_client.c | 5 +++- fs/ceph/snap.c | 6 ++--- 7 files changed, 72 insertions(+), 46 deletions(-)