in->ctime = ceph_clock_now(cct);
in->cap_dirtier_uid = uid;
in->cap_dirtier_gid = gid;
- in->btime = utime_t(stx->stx_btime, stx->stx_btime_ns);
+ in->btime = utime_t(stx->stx_btime);
mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
mask &= ~CEPH_SETATTR_BTIME;
ldout(cct,10) << "changing btime to " << in->btime << dendl;
if (in->caps_issued_mask(CEPH_CAP_FILE_EXCL)) {
if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME)) {
if (mask & CEPH_SETATTR_MTIME)
- in->mtime = utime_t(stx->stx_mtime, stx->stx_mtime_ns);
+ in->mtime = utime_t(stx->stx_mtime);
if (mask & CEPH_SETATTR_ATIME)
- in->atime = utime_t(stx->stx_atime, stx->stx_atime_ns);
+ in->atime = utime_t(stx->stx_atime);
in->ctime = ceph_clock_now(cct);
in->cap_dirtier_uid = uid;
in->cap_dirtier_gid = gid;
ldout(cct,10) << "changing gid to " << stx->stx_gid << dendl;
}
if (mask & CEPH_SETATTR_MTIME) {
- req->head.args.setattr.mtime = utime_t(stx->stx_mtime, stx->stx_mtime_ns);
+ req->head.args.setattr.mtime = utime_t(stx->stx_mtime);
req->inode_drop |= CEPH_CAP_AUTH_SHARED | CEPH_CAP_FILE_RD |
CEPH_CAP_FILE_WR;
}
if (mask & CEPH_SETATTR_ATIME) {
- req->head.args.setattr.atime = utime_t(stx->stx_atime, stx->stx_atime_ns);
+ req->head.args.setattr.atime = utime_t(stx->stx_atime);
req->inode_drop |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
CEPH_CAP_FILE_WR;
}
if (mask & CEPH_SETATTR_BTIME) {
- req->head.args.setattr.btime = utime_t(stx->stx_btime, stx->stx_btime_ns);
+ req->head.args.setattr.btime = utime_t(stx->stx_btime);
req->inode_drop |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
CEPH_CAP_FILE_WR;
}
stx->stx_mode = st->st_mode;
stx->stx_uid = st->st_uid;
stx->stx_gid = st->st_gid;
- stx->stx_mtime = stat_get_mtime_sec(st);
- stx->stx_mtime_ns = stat_get_mtime_nsec(st);
- stx->stx_atime = stat_get_atime_sec(st);
- stx->stx_atime_ns = stat_get_atime_nsec(st);
+ stx->stx_mtime = st->st_mtim;
+ stx->stx_atime = st->st_atim;
}
int Client::__setattrx(Inode *in, struct ceph_statx *stx, int mask, int uid, int gid,
stx->stx_uid = in->uid;
stx->stx_gid = in->gid;
stx->stx_mode = in->mode;
- stx->stx_btime = in->btime.sec();
- stx->stx_btime_ns = in->btime.nsec();
+ in->btime.to_timespec(&stx->stx_btime);
stx->stx_mask |= (CEPH_STATX_MODE|CEPH_STATX_UID|CEPH_STATX_GID|CEPH_STATX_BTIME);
}
}
if (mask & CEPH_CAP_FILE_SHARED) {
- if (in->ctime > in->mtime) {
- stx->stx_ctime = in->ctime.sec();
- stx->stx_ctime_ns = in->ctime.nsec();
- } else {
- stx->stx_ctime = in->mtime.sec();
- stx->stx_ctime_ns = in->mtime.nsec();
- }
- stx->stx_atime = in->atime.sec();
- stx->stx_atime_ns = in->atime.nsec();
- stx->stx_mtime = in->mtime.sec();
- stx->stx_mtime_ns = in->mtime.nsec();
+
+ if (in->ctime > in->mtime)
+ in->ctime.to_timespec(&stx->stx_ctime);
+ else
+ in->mtime.to_timespec(&stx->stx_ctime);
+
+ in->atime.to_timespec(&stx->stx_atime);
+ in->mtime.to_timespec(&stx->stx_mtime);
stx->stx_version = in->change_attr;
if (in->is_dir()) {
ceph_shutdown(cmount);
}
+static inline bool
+timespec_eq(timespec const& lhs, timespec const& rhs)
+{
+ return lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec;
+}
+
TEST(LibCephFS, Btime) {
struct ceph_mount_info *cmount;
ASSERT_EQ(ceph_create(&cmount, NULL), 0);
ASSERT_EQ(ceph_fstatx(cmount, fd, &stx, CEPH_STATX_CTIME|CEPH_STATX_BTIME, 0), 0);
ASSERT_TRUE(stx.stx_mask & (CEPH_STATX_CTIME|CEPH_STATX_BTIME));
- ASSERT_EQ(stx.stx_btime, stx.stx_ctime);
- ASSERT_EQ(stx.stx_btime_ns, stx.stx_ctime_ns);
+ ASSERT_TRUE(timespec_eq(stx.stx_ctime, stx.stx_btime));
ceph_close(cmount, fd);
ASSERT_EQ(ceph_statx(cmount, filename, &stx, CEPH_STATX_CTIME|CEPH_STATX_BTIME, 0), 0);
+ ASSERT_TRUE(timespec_eq(stx.stx_ctime, stx.stx_btime));
ASSERT_TRUE(stx.stx_mask & (CEPH_STATX_CTIME|CEPH_STATX_BTIME));
- ASSERT_EQ(stx.stx_btime, stx.stx_ctime);
- ASSERT_EQ(stx.stx_btime_ns, stx.stx_ctime_ns);
- int64_t old_btime = stx.stx_btime;
- int32_t old_btime_ns = stx.stx_btime_ns;
+ struct timespec old_btime = stx.stx_btime;
/* Now sleep, do a chmod and verify that the ctime changed, but btime didn't */
sleep(1);
ASSERT_EQ(ceph_chmod(cmount, filename, 0644), 0);
- ASSERT_EQ(ceph_statx(cmount, filename, &stx, CEPH_STATX_BTIME, 0), 0);
+ ASSERT_EQ(ceph_statx(cmount, filename, &stx, CEPH_STATX_CTIME|CEPH_STATX_BTIME, 0), 0);
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_BTIME);
- ASSERT_EQ(stx.stx_btime, old_btime);
- ASSERT_EQ(stx.stx_btime_ns, old_btime_ns);
- ASSERT_FALSE(old_btime == stx.stx_ctime && old_btime_ns == stx.stx_ctime_ns);
+ ASSERT_TRUE(timespec_eq(stx.stx_btime, old_btime));
+ ASSERT_FALSE(timespec_eq(stx.stx_ctime, stx.stx_btime));
ceph_shutdown(cmount);
}
ceph_close(cmount, fd);
struct ceph_statx stx;
+ struct timespec old_btime = { 1, 2 };
- stx.stx_btime = 1;
- stx.stx_btime_ns = 2;
+ stx.stx_btime = old_btime;
ASSERT_EQ(ceph_setattrx(cmount, filename, &stx, CEPH_SETATTR_BTIME, 0), 0);
ASSERT_EQ(ceph_statx(cmount, filename, &stx, CEPH_STATX_BTIME, 0), 0);
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_BTIME);
-
- ASSERT_EQ(stx.stx_btime, 1);
- ASSERT_EQ(stx.stx_btime_ns, 2);
+ ASSERT_TRUE(timespec_eq(stx.stx_btime, old_btime));
ceph_shutdown(cmount);
}
ASSERT_EQ(ceph_ll_lookup_root(cmount2, &root2), 0);
ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &st, &file2, getuid(), getgid()), 0);
- int64_t old_ctime = stat_get_ctime_sec(&st);
- int32_t old_ctime_ns = stat_get_ctime_nsec(&st);
+ struct timespec old_ctime = st.st_ctim;
/*
* Now sleep, do a chmod on the first client and the see whether we get a
struct ceph_statx stx;
ASSERT_EQ(ceph_ll_getattrx(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, getuid(), getgid()), 0);
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME);
- ASSERT_EQ(stx.stx_ctime, old_ctime);
- ASSERT_EQ(stx.stx_ctime_ns, old_ctime_ns);
+ ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec &&
+ stx.stx_ctime.tv_nsec == old_ctime.tv_nsec);
ceph_shutdown(cmount1);
ceph_shutdown(cmount2);