Commit 15eefe2a authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 'vfs_timespec64' of https://github.com/deepa-hub/vfs into vfs-timespec64

Pull the timespec64 conversion from Deepa Dinamani:
 "The series aims to switch vfs timestamps to use
  struct timespec64. Currently vfs uses struct timespec,
  which is not y2038 safe.

  The flag patch applies cleanly. I've not seen the timestamps
  update logic change often. The series applies cleanly on 4.17-rc6
  and linux-next tip (top commit: next-20180517).

  I'm not sure how to merge this kind of a series with a flag patch.
  We are targeting 4.18 for this.
  Let me know if you have other suggestions.

  The series involves the following:
  1. Add vfs helper functions for supporting struct timepec64 timestamps.
  2. Cast prints of vfs timestamps to avoid warnings after the switch.
  3. Simplify code using vfs timestamps so that the actual
     replacement becomes easy.
  4. Convert vfs timestamps to use struct timespec64 using a script.
     This is a flag day patch.

  I've tried to keep the conversions with the script simple, to
  aid in the reviews. I've kept all the internal filesystem data
  structures and function signatures the same.

  Next steps:
  1. Convert APIs that can handle timespec64, instead of converting
     timestamps at the boundaries.
  2. Update internal data structures to avoid timestamp conversions."

I've pulled it into a branch based on top of the NFS changes that
are now in mainline, so I could resolve the non-obvious conflict
between the two while merging.
Signed-off-by: 's avatarArnd Bergmann <arnd@arndb.de>
parents 93b7f7ad 95582b00
......@@ -28,10 +28,9 @@ static int efi_pstore_close(struct pstore_info *psi)
return 0;
}
static inline u64 generic_id(unsigned long timestamp,
unsigned int part, int count)
static inline u64 generic_id(u64 timestamp, unsigned int part, int count)
{
return ((u64) timestamp * 100 + part) * 1000 + count;
return (timestamp * 100 + part) * 1000 + count;
}
static int efi_pstore_read_func(struct efivar_entry *entry,
......@@ -42,7 +41,8 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
int i;
int cnt;
unsigned int part;
unsigned long time, size;
unsigned long size;
u64 time;
if (efi_guidcmp(entry->var.VendorGuid, vendor))
return 0;
......@@ -50,7 +50,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
for (i = 0; i < DUMP_NAME_LEN; i++)
name[i] = entry->var.VariableName[i];
if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
if (sscanf(name, "dump-type%u-%u-%d-%llu-%c",
&record->type, &part, &cnt, &time, &data_type) == 5) {
record->id = generic_id(time, part, cnt);
record->part = part;
......@@ -62,7 +62,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
else
record->compressed = false;
record->ecc_notice_size = 0;
} else if (sscanf(name, "dump-type%u-%u-%d-%lu",
} else if (sscanf(name, "dump-type%u-%u-%d-%llu",
&record->type, &part, &cnt, &time) == 4) {
record->id = generic_id(time, part, cnt);
record->part = part;
......@@ -71,7 +71,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
record->time.tv_nsec = 0;
record->compressed = false;
record->ecc_notice_size = 0;
} else if (sscanf(name, "dump-type%u-%u-%lu",
} else if (sscanf(name, "dump-type%u-%u-%llu",
&record->type, &part, &time) == 3) {
/*
* Check if an old format,
......@@ -250,9 +250,10 @@ static int efi_pstore_write(struct pstore_record *record)
/* Since we copy the entire length of name, make sure it is wiped. */
memset(name, 0, sizeof(name));
snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu-%c",
snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lld-%c",
record->type, record->part, record->count,
record->time.tv_sec, record->compressed ? 'C' : 'D');
(long long)record->time.tv_sec,
record->compressed ? 'C' : 'D');
for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = name[i];
......@@ -327,15 +328,15 @@ static int efi_pstore_erase(struct pstore_record *record)
char name[DUMP_NAME_LEN];
int ret;
snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu",
snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lld",
record->type, record->part, record->count,
record->time.tv_sec);
(long long)record->time.tv_sec);
ret = efi_pstore_erase_name(name);
if (ret != -ENOENT)
return ret;
snprintf(name, sizeof(name), "dump-type%u-%u-%lu",
record->type, record->part, record->time.tv_sec);
snprintf(name, sizeof(name), "dump-type%u-%u-%lld",
record->type, record->part, (long long)record->time.tv_sec);
ret = efi_pstore_erase_name(name);
return ret;
......
......@@ -1482,8 +1482,9 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
}
if (attr->ia_valid & (ATTR_MTIME | ATTR_CTIME))
CDEBUG(D_INODE, "setting mtime %lu, ctime %lu, now = %llu\n",
LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
CDEBUG(D_INODE, "setting mtime %llu, ctime %llu, now = %llu\n",
(unsigned long long)LTIME_S(attr->ia_mtime),
(unsigned long long)LTIME_S(attr->ia_ctime),
(s64)ktime_get_real_seconds());
if (S_ISREG(inode->i_mode))
......@@ -1760,9 +1761,10 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md)
if (body->mbo_valid & OBD_MD_FLMTIME) {
if (body->mbo_mtime > LTIME_S(inode->i_mtime)) {
CDEBUG(D_INODE,
"setting ino %lu mtime from %lu to %llu\n",
inode->i_ino, LTIME_S(inode->i_mtime),
body->mbo_mtime);
"setting ino %lu mtime from %llu to %llu\n",
inode->i_ino,
(unsigned long long)LTIME_S(inode->i_mtime),
(unsigned long long)body->mbo_mtime);
LTIME_S(inode->i_mtime) = body->mbo_mtime;
}
lli->lli_mtime = body->mbo_mtime;
......
......@@ -844,8 +844,9 @@ void ll_update_times(struct ptlrpc_request *request, struct inode *inode)
LASSERT(body);
if (body->mbo_valid & OBD_MD_FLMTIME &&
body->mbo_mtime > LTIME_S(inode->i_mtime)) {
CDEBUG(D_INODE, "setting fid " DFID " mtime from %lu to %llu\n",
PFID(ll_inode2fid(inode)), LTIME_S(inode->i_mtime),
CDEBUG(D_INODE, "setting fid " DFID " mtime from %llu to %llu\n",
PFID(ll_inode2fid(inode)),
(unsigned long long)LTIME_S(inode->i_mtime),
body->mbo_mtime);
LTIME_S(inode->i_mtime) = body->mbo_mtime;
}
......
......@@ -3031,11 +3031,12 @@ static int lmv_merge_attr(struct obd_export *exp,
for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
struct inode *inode = lsm->lsm_md_oinfo[i].lmo_root;
CDEBUG(D_INFO, "" DFID " size %llu, blocks %llu nlink %u, atime %lu ctime %lu, mtime %lu.\n",
CDEBUG(D_INFO, "" DFID " size %llu, blocks %llu nlink %u, atime %llu ctime %llu, mtime %llu.\n",
PFID(&lsm->lsm_md_oinfo[i].lmo_fid),
i_size_read(inode), (unsigned long long)inode->i_blocks,
inode->i_nlink, LTIME_S(inode->i_atime),
LTIME_S(inode->i_ctime), LTIME_S(inode->i_mtime));
inode->i_nlink, (unsigned long long)LTIME_S(inode->i_atime),
(unsigned long long)LTIME_S(inode->i_ctime),
(unsigned long long)LTIME_S(inode->i_mtime));
/* for slave stripe, it needs to subtract nlink for . and .. */
if (i)
......
......@@ -129,9 +129,9 @@ int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data,
}
if (op_data->op_attr.ia_valid & (ATTR_MTIME | ATTR_CTIME))
CDEBUG(D_INODE, "setting mtime %ld, ctime %ld\n",
LTIME_S(op_data->op_attr.ia_mtime),
LTIME_S(op_data->op_attr.ia_ctime));
CDEBUG(D_INODE, "setting mtime %lld, ctime %lld\n",
(long long)LTIME_S(op_data->op_attr.ia_mtime),
(long long)LTIME_S(op_data->op_attr.ia_ctime));
mdc_setattr_pack(req, op_data, ea, ealen);
ptlrpc_request_set_replen(req);
......
......@@ -60,9 +60,9 @@ void obdo_from_inode(struct obdo *dst, struct inode *src, u32 valid)
u32 newvalid = 0;
if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME))
CDEBUG(D_INODE, "valid %x, new time %lu/%lu\n",
valid, LTIME_S(src->i_mtime),
LTIME_S(src->i_ctime));
CDEBUG(D_INODE, "valid %x, new time %llu/%llu\n",
valid, (long long)LTIME_S(src->i_mtime),
(long long)LTIME_S(src->i_ctime));
if (valid & OBD_MD_FLATIME) {
dst->o_atime = LTIME_S(src->i_atime);
......
......@@ -867,8 +867,13 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
i = -EIO;
tty_ldisc_deref(ld);
if (i > 0)
tty_update_time(&inode->i_atime);
if (i > 0) {
struct timespec ts;
ts = timespec64_to_timespec(inode->i_atime);
tty_update_time(&ts);
inode->i_atime = timespec_to_timespec64(ts);
}
return i;
}
......@@ -969,7 +974,11 @@ static inline ssize_t do_tty_write(
cond_resched();
}
if (written) {
tty_update_time(&file_inode(file)->i_mtime);
struct timespec ts;
ts = timespec64_to_timespec(file_inode(file)->i_mtime);
tty_update_time(&ts);
file_inode(file)->i_mtime = timespec_to_timespec64(ts);
ret = written;
}
out:
......
......@@ -1297,7 +1297,7 @@ ffs_sb_make_inode(struct super_block *sb, void *data,
inode = new_inode(sb);
if (likely(inode)) {
struct timespec ts = current_time(inode);
struct timespec64 ts = current_time(inode);
inode->i_ino = get_next_ino();
inode->i_mode = perms->mode;
......
......@@ -199,7 +199,7 @@ adfs_adfs2unix_time(struct timespec *tv, struct inode *inode)
return;
cur_time:
*tv = current_time(inode);
*tv = timespec64_to_timespec(current_time(inode));
return;
too_early:
......@@ -242,6 +242,7 @@ adfs_unix2adfs_time(struct inode *inode, unsigned int secs)
struct inode *
adfs_iget(struct super_block *sb, struct object_info *obj)
{
struct timespec ts;
struct inode *inode;
inode = new_inode(sb);
......@@ -270,7 +271,9 @@ adfs_iget(struct super_block *sb, struct object_info *obj)
ADFS_I(inode)->stamped = ((obj->loadaddr & 0xfff00000) == 0xfff00000);
inode->i_mode = adfs_atts2mode(sb, inode);
adfs_adfs2unix_time(&inode->i_mtime, inode);
ts = timespec64_to_timespec(inode->i_mtime);
adfs_adfs2unix_time(&ts, inode);
inode->i_mtime = timespec_to_timespec64(ts);
inode->i_atime = inode->i_mtime;
inode->i_ctime = inode->i_mtime;
......
......@@ -72,7 +72,7 @@ void afs_update_inode_from_status(struct afs_vnode *vnode,
const afs_dataversion_t *expected_version,
u8 flags)
{
struct timespec t;
struct timespec64 t;
umode_t mode;
t.tv_sec = status->mtime_client;
......
......@@ -163,14 +163,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);
inode->i_atime = timespec64_trunc(attr->ia_atime,
inode->i_sb->s_time_gran);
if (ia_valid & ATTR_MTIME)
inode->i_mtime = timespec_trunc(attr->ia_mtime,
inode->i_sb->s_time_gran);
inode->i_mtime = timespec64_trunc(attr->ia_mtime,
inode->i_sb->s_time_gran);
if (ia_valid & ATTR_CTIME)
inode->i_ctime = timespec_trunc(attr->ia_ctime,
inode->i_sb->s_time_gran);
inode->i_ctime = timespec64_trunc(attr->ia_ctime,
inode->i_sb->s_time_gran);
if (ia_valid & ATTR_MODE) {
umode_t mode = attr->ia_mode;
......@@ -207,7 +207,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 timespec64 now;
unsigned int ia_valid = attr->ia_valid;
WARN_ON_ONCE(!inode_is_locked(inode));
......
......@@ -126,7 +126,7 @@ static int bad_inode_fiemap(struct inode *inode,
return -EIO;
}
static int bad_inode_update_time(struct inode *inode, struct timespec *time,
static int bad_inode_update_time(struct inode *inode, struct timespec64 *time,
int flags)
{
return -EIO;
......
......@@ -1842,16 +1842,16 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
static void update_time_for_write(struct inode *inode)
{
struct timespec now;
struct timespec64 now;
if (IS_NOCMTIME(inode))
return;
now = current_time(inode);
if (!timespec_equal(&inode->i_mtime, &now))
if (!timespec64_equal(&inode->i_mtime, &now))
inode->i_mtime = now;
if (!timespec_equal(&inode->i_ctime, &now))
if (!timespec64_equal(&inode->i_ctime, &now))
inode->i_ctime = now;
if (IS_I_VERSION(inode))
......
......@@ -5777,7 +5777,7 @@ static struct inode *new_simple_dir(struct super_block *s,
inode->i_mtime = current_time(inode);
inode->i_atime = inode->i_mtime;
inode->i_ctime = inode->i_mtime;
BTRFS_I(inode)->i_otime = inode->i_mtime;
BTRFS_I(inode)->i_otime = timespec64_to_timespec(inode->i_mtime);
return inode;
}
......@@ -6131,7 +6131,7 @@ static int btrfs_dirty_inode(struct inode *inode)
* This is a copy of file_update_time. We need this so we can return error on
* ENOSPC for updating the inode in the case of file write and mmap writes.
*/
static int btrfs_update_time(struct inode *inode, struct timespec *now,
static int btrfs_update_time(struct inode *inode, struct timespec64 *now,
int flags)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
......@@ -6386,7 +6386,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
inode->i_mtime = current_time(inode);
inode->i_atime = inode->i_mtime;
inode->i_ctime = inode->i_mtime;
BTRFS_I(inode)->i_otime = inode->i_mtime;
BTRFS_I(inode)->i_otime = timespec64_to_timespec(inode->i_mtime);
inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_inode_item);
......@@ -9465,7 +9465,7 @@ static int btrfs_rename_exchange(struct inode *old_dir,
struct btrfs_root *dest = BTRFS_I(new_dir)->root;
struct inode *new_inode = new_dentry->d_inode;
struct inode *old_inode = old_dentry->d_inode;
struct timespec ctime = current_time(old_inode);
struct timespec64 ctime = current_time(old_inode);
struct dentry *parent;
u64 old_ino = btrfs_ino(BTRFS_I(old_inode));
u64 new_ino = btrfs_ino(BTRFS_I(new_inode));
......
......@@ -417,7 +417,7 @@ static noinline int create_subvol(struct inode *dir,
struct btrfs_root *root = BTRFS_I(dir)->root;
struct btrfs_root *new_root;
struct btrfs_block_rsv block_rsv;
struct timespec cur_time = current_time(dir);
struct timespec64 cur_time = current_time(dir);
struct inode *inode;
int ret;
int err;
......@@ -4996,7 +4996,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file,
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_root_item *root_item = &root->root_item;
struct btrfs_trans_handle *trans;
struct timespec ct = current_time(inode);
struct timespec64 ct = current_time(inode);
int ret = 0;
int received_uuid_changed;
......
......@@ -485,9 +485,9 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
struct btrfs_root_item *item = &root->root_item;
struct timespec ct;
struct timespec64 ct;
ktime_get_real_ts(&ct);
ktime_get_real_ts64(&ct);
spin_lock(&root->root_item_lock);
btrfs_set_root_ctransid(item, trans->transid);
btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
......
......@@ -1428,7 +1428,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
struct dentry *dentry;
struct extent_buffer *tmp;
struct extent_buffer *old;
struct timespec cur_time;
struct timespec64 cur_time;
int ret = 0;
u64 to_reserve = 0;
u64 index = 0;
......
......@@ -574,6 +574,7 @@ static u64 get_writepages_data_length(struct inode *inode,
*/
static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
{
struct timespec ts;
struct inode *inode;
struct ceph_inode_info *ci;
struct ceph_fs_client *fsc;
......@@ -624,11 +625,12 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
set_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC);
set_page_writeback(page);
ts = timespec64_to_timespec(inode->i_mtime);
err = ceph_osdc_writepages(&fsc->client->osdc, ceph_vino(inode),
&ci->i_layout, snapc, page_off, len,
ceph_wbc.truncate_seq,
ceph_wbc.truncate_size,
&inode->i_mtime, &page, 1);
&ts, &page, 1);
if (err < 0) {
struct writeback_control tmp_wbc;
if (!wbc)
......@@ -1131,7 +1133,7 @@ static int ceph_writepages_start(struct address_space *mapping,
pages = NULL;
}
req->r_mtime = inode->i_mtime;
req->r_mtime = timespec64_to_timespec(inode->i_mtime);
rc = ceph_osdc_start_request(&fsc->client->osdc, req, true);
BUG_ON(rc);
req = NULL;
......@@ -1731,7 +1733,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
goto out;
}
req->r_mtime = inode->i_mtime;
req->r_mtime = timespec64_to_timespec(inode->i_mtime);
err = ceph_osdc_start_request(&fsc->client->osdc, req, false);
if (!err)
err = ceph_osdc_wait_request(&fsc->client->osdc, req);
......@@ -1773,7 +1775,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page)
goto out_put;
}
req->r_mtime = inode->i_mtime;
req->r_mtime = timespec64_to_timespec(inode->i_mtime);
err = ceph_osdc_start_request(&fsc->client->osdc, req, false);
if (!err)
err = ceph_osdc_wait_request(&fsc->client->osdc, req);
......@@ -1934,7 +1936,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci,
0, false, true);
err = ceph_osdc_start_request(&fsc->client->osdc, rd_req, false);
wr_req->r_mtime = ci->vfs_inode.i_mtime;
wr_req->r_mtime = timespec64_to_timespec(ci->vfs_inode.i_mtime);
wr_req->r_abort_on_full = true;
err2 = ceph_osdc_start_request(&fsc->client->osdc, wr_req, false);
......
......@@ -130,7 +130,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(
memset(&aux, 0, sizeof(aux));
aux.version = ci->i_version;
aux.mtime = inode->i_mtime;
aux.mtime = timespec64_to_timespec(inode->i_mtime);
if (memcmp(data, &aux, sizeof(aux)) != 0)
return FSCACHE_CHECKAUX_OBSOLETE;
......@@ -163,7 +163,7 @@ void ceph_fscache_register_inode_cookie(struct inode *inode)
if (!ci->fscache) {
memset(&aux, 0, sizeof(aux));
aux.version = ci->i_version;
aux.mtime = inode->i_mtime;
aux.mtime = timespec64_to_timespec(inode->i_mtime);
ci->fscache = fscache_acquire_cookie(fsc->fscache,
&ceph_fscache_inode_object_def,
&ci->i_vino, sizeof(ci->i_vino),
......
......@@ -1358,9 +1358,9 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
arg.xattr_buf = NULL;
}
arg.mtime = inode->i_mtime;
arg.atime = inode->i_atime;
arg.ctime = inode->i_ctime;
arg.mtime = timespec64_to_timespec(inode->i_mtime);
arg.atime = timespec64_to_timespec(inode->i_atime);
arg.ctime = timespec64_to_timespec(inode->i_ctime);
arg.op = op;
arg.caps = cap->implemented;
......
......@@ -924,7 +924,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
int num_pages = 0;
int flags;
int ret;
struct timespec mtime = current_time(inode);
struct timespec mtime = timespec64_to_timespec(current_time(inode));
size_t count = iov_iter_count(iter);
loff_t pos = iocb->ki_pos;
bool write = iov_iter_rw(iter) == WRITE;
......@@ -1132,7 +1132,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
int flags;
int ret;
bool check_caps = false;
struct timespec mtime = current_time(inode);
struct timespec mtime = timespec64_to_timespec(current_time(inode));
size_t count = iov_iter_count(from);
if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
......@@ -1664,7 +1664,7 @@ static int ceph_zero_partial_object(struct inode *inode,
goto out;
}
req->r_mtime = inode->i_mtime;
req->r_mtime = timespec64_to_timespec(inode->i_mtime);
ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
if (!ret) {
ret = ceph_osdc_wait_request(&fsc->client->osdc, req);
......
......@@ -662,6 +662,9 @@ 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 timespec64 ctime64 = timespec_to_timespec64(*ctime);
struct timespec64 mtime64 = timespec_to_timespec64(*mtime);
struct timespec64 atime64 = timespec_to_timespec64(*atime);
int warn = 0;
if (issued & (CEPH_CAP_FILE_EXCL|
......@@ -670,39 +673,39 @@ void ceph_fill_file_time(struct inode *inode, int issued,
CEPH_CAP_AUTH_EXCL|
CEPH_CAP_XATTR_EXCL)) {
if (ci->i_version == 0 ||
timespec_compare(ctime, &inode->i_ctime) > 0) {
dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
ctime->tv_sec, ctime->tv_nsec);
inode->i_ctime = *ctime;
timespec64_compare(&ctime64, &inode->i_ctime) > 0) {
dout("ctime %lld.%09ld -> %lld.%09ld inc w/ cap\n",
(long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
(long long)ctime->tv_sec, ctime->tv_nsec);
inode->i_ctime = ctime64;
}
if (ci->i_version == 0 ||
ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
/* the MDS did a utimes() */
dout("mtime %ld.%09ld -> %ld.%09ld "
dout("mtime %lld.%09ld -> %lld.%09ld "
"tw %d -> %d\n",
inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
mtime->tv_sec, mtime->tv_nsec,
(long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
(long long)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 = mtime64;
inode->i_atime = atime64;
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) {
dout("mtime %ld.%09ld -> %ld.%09ld inc\n",
inode->i_mtime.tv_sec,
if (timespec64_compare(&mtime64, &inode->i_mtime) > 0) {
dout("mtime %lld.%09ld -> %lld.%09ld inc\n",
(long long)inode->i_mtime.tv_sec,
inode->i_mtime.tv_nsec,
mtime->tv_sec, mtime->tv_nsec);
inode->i_mtime = *mtime;
(long long)mtime->tv_sec, mtime->tv_nsec);
inode->i_mtime = mtime64;
}
if (timespec_compare(atime, &inode->i_atime) > 0) {
dout("atime %ld.%09ld -> %ld.%09ld inc\n",
inode->i_atime.tv_sec,
if (timespec64_compare(&atime64, &inode->i_atime) > 0) {
dout("atime %lld.%09ld -> %lld.%09ld inc\n",
(long long)inode->i_atime.tv_sec,
inode->i_atime.tv_nsec,
atime->tv_sec, atime->tv_nsec);
inode->i_atime = *atime;
(long long)atime->tv_sec, atime->tv_nsec);
inode->i_atime = atime64;
}
} else if (issued & CEPH_CAP_FILE_EXCL) {
/* we did a utimes(); ignore mds values */
......@@ -712,9 +715,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 = ctime64;
inode->i_mtime = mtime64;
inode->i_atime = atime64;
ci->i_time_warp_seq = time_warp_seq;
} else {
warn = 1;
......@@ -1941,6 +1944,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
int err = 0;
int inode_dirty_flags = 0;
bool lock_snap_rwsem = false;
struct timespec ts;
prealloc_cf = ceph_alloc_cap_flush();
if (!prealloc_cf)
......@@ -2015,44 +2019,44 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
}
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);
dout("setattr %p atime %lld.%ld -> %lld.%ld\n", inode,
(long long)inode->i_atime.tv_sec, inode->i_atime.tv_nsec,
(long long)attr->ia_atime.tv_sec, attr->ia_atime.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,
timespec64_compare(&inode->i_atime,
&attr->ia_atime) < 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)) {
ceph_encode_timespec(&req->r_args.setattr.atime,
&attr->ia_atime);
!timespec64_equal(&inode->i_atime, &attr->ia_atime)) {
ts = timespec64_to_timespec(attr->ia_atime);
ceph_encode_timespec(&req->r_args.setattr.atime, &ts);
mask |= CEPH_SETATTR_ATIME;
release |= CEPH_CAP_FILE_SHARED |
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
}
}
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);
dout("setattr %p mtime %lld.%ld -> %lld.%ld\n", inode,
(long long)inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
(long long)attr->ia_mtime.tv_sec, attr->ia_mtime.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,
timespec64_compare(&inode->i_mtime,
&attr->ia_mtime) < 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)) {
ceph_encode_timespec(&req->r_args.setattr.mtime,
&attr->ia_mtime);
!timespec64_equal(&inode->i_mtime, &attr->ia_mtime)) {
ts = timespec64_to_timespec(attr->ia_mtime);
ceph_encode_timespec(&req->r_args.setattr.mtime, &ts);
mask |= CEPH_SETATTR_MTIME;
release |= CEPH_CAP_FILE_SHARED |
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
......@@ -2082,9 +2086,9 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
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,
dout("setattr %p ctime %lld.%ld -> %lld.%ld (%s)\n", inode,
(long long)inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
(long long)attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec,
only ? "ctime only" : "ignored");
if (only) {
/*
......@@ -2126,7 +2130,7 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
req->r_inode_drop = release;
req->r_args.setattr.mask = cpu_to_le32(mask);
req->r_num_caps = 1;
req->r_stamp = attr->ia_ctime;
req->r_stamp = timespec64_to_timespec(attr->ia_ctime);
err = ceph_mdsc_do_request(mdsc, NULL, req);
}
dout("setattr %p result=%d (%s locally, %d remote)\n", inode, err,
......
......@@ -2958,12 +2958,15 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap,
rec.v2.flock_len = (__force __le32)
((ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) ? 0 : 1);
} else {
struct timespec ts;
rec.v1.cap_id = cpu_to_le64(cap->cap_id);