summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Watkins <noahwatkins@gmail.com>2013-07-20 18:41:39 -0700
committerNoah Watkins <noahwatkins@gmail.com>2013-07-20 18:41:39 -0700
commitf85824c86dec496762e36fb79fbd5c1953b191da (patch)
tree3087aa59e8d504130ac7292ff08176560aa6fc4c
parent0c308f424383f13947cd9ba559a023933e50fbb6 (diff)
downloadceph-f85824c86dec496762e36fb79fbd5c1953b191da.tar.gz
client: use struct stat member tests for time
Signed-off-by: Noah Watkins <noahwatkins@gmail.com>
-rw-r--r--configure.ac11
-rw-r--r--src/Makefile.am1
-rw-r--r--src/client/Client.cc45
-rw-r--r--src/include/stat.h145
4 files changed, 180 insertions, 22 deletions
diff --git a/configure.ac b/configure.ac
index b650e950414..8e4ef277585 100644
--- a/configure.ac
+++ b/configure.ac
@@ -520,6 +520,17 @@ AC_CHECK_FUNC([fallocate],
[AC_DEFINE([CEPH_HAVE_FALLOCATE], [], [fallocate(2) is supported])],
[])
+#
+# Test for time-related `struct stat` members.
+#
+
+AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],
+ [AC_DEFINE(HAVE_STAT_TV_NSEC, 1,
+ [Define if you have struct stat.st_mtim.tv_nsec])])
+
+AC_CHECK_MEMBER([struct stat.st_mtimespec.tv_nsec],
+ [AC_DEFINE(HAVE_STAT_ST_TIMESPEC, 1,
+ [Define if you have struct stat.st_mtimespec.tv_nsec])])
# Checks for typedefs, structures, and compiler characteristics.
#AC_HEADER_STDBOOL
diff --git a/src/Makefile.am b/src/Makefile.am
index cdbf187035a..234d084eaa0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1918,6 +1918,7 @@ noinst_HEADERS = \
include/rbd/librbd.h\
include/rbd/librbd.hpp\
include/util.h\
+ include/stat.h\
librados/snap_set_diff.h\
librados/AioCompletionImpl.h\
librados/IoCtxImpl.h\
diff --git a/src/client/Client.cc b/src/client/Client.cc
index ae7ddf65db4..276c194f1a2 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -80,6 +80,7 @@ using namespace std;
#include "ObjecterWriteback.h"
#include "include/assert.h"
+#include "include/stat.h"
#undef dout_prefix
#define dout_prefix *_dout << "client." << whoami << " "
@@ -4389,9 +4390,9 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid, I
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(attr->st_mtim.tv_sec, attr->st_mtim.tv_nsec);
+ in->mtime = utime_t(stat_get_mtime_sec(attr), stat_get_mtime_nsec(attr));
if (mask & CEPH_SETATTR_ATIME)
- in->atime = utime_t(attr->st_atim.tv_sec, attr->st_atim.tv_nsec);
+ in->atime = utime_t(stat_get_atime_sec(attr), stat_get_atime_nsec(attr));
in->ctime = ceph_clock_now(cct);
in->time_warp_seq++;
mark_caps_dirty(in, CEPH_CAP_FILE_EXCL);
@@ -4421,14 +4422,14 @@ int Client::_setattr(Inode *in, struct stat *attr, int mask, int uid, int gid, I
req->inode_drop |= CEPH_CAP_AUTH_SHARED;
}
if (mask & CEPH_SETATTR_MTIME) {
- req->head.args.setattr.mtime =
- utime_t(attr->st_mtim.tv_sec, attr->st_mtim.tv_nsec);
+ utime_t mtime = utime_t(stat_get_mtime_sec(attr), stat_get_mtime_nsec(attr));
+ req->head.args.setattr.mtime = 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(attr->st_atim.tv_sec, attr->st_atim.tv_nsec);
+ utime_t atime = utime_t(stat_get_atime_sec(attr), stat_get_atime_nsec(attr));
+ req->head.args.setattr.atime = atime;
req->inode_drop |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
CEPH_CAP_FILE_WR;
}
@@ -4538,16 +4539,16 @@ int Client::fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat, nest_inf
st->st_uid = in->uid;
st->st_gid = in->gid;
if (in->ctime.sec() > in->mtime.sec()) {
- st->st_ctim.tv_sec = in->ctime.sec();
- st->st_ctim.tv_nsec = in->ctime.nsec();
+ stat_set_ctime_sec(st, in->ctime.sec());
+ stat_set_ctime_nsec(st, in->ctime.nsec());
} else {
- st->st_ctim.tv_sec = in->mtime.sec();
- st->st_ctim.tv_nsec = in->mtime.nsec();
+ stat_set_ctime_sec(st, in->mtime.sec());
+ stat_set_ctime_nsec(st, in->mtime.nsec());
}
- st->st_atim.tv_sec = in->atime.sec();
- st->st_atim.tv_nsec = in->atime.nsec();
- st->st_mtim.tv_sec = in->mtime.sec();
- st->st_mtim.tv_nsec = in->mtime.nsec();
+ stat_set_atime_sec(st, in->atime.sec());
+ stat_set_atime_nsec(st, in->atime.nsec());
+ stat_set_mtime_sec(st, in->mtime.sec());
+ stat_set_mtime_nsec(st, in->mtime.nsec());
if (in->is_dir()) {
//st->st_size = in->dirstat.size();
st->st_size = in->rstat.rbytes;
@@ -4693,10 +4694,10 @@ int Client::utime(const char *relpath, struct utimbuf *buf)
if (r < 0)
return r;
struct stat attr;
- attr.st_mtim.tv_sec = buf->modtime;
- attr.st_mtim.tv_nsec = 0;
- attr.st_atim.tv_sec = buf->actime;
- attr.st_atim.tv_nsec = 0;
+ stat_set_mtime_sec(&attr, buf->modtime);
+ stat_set_mtime_nsec(&attr, 0);
+ stat_set_atime_sec(&attr, buf->actime);
+ stat_set_atime_nsec(&attr, 0);
return _setattr(in, &attr, CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME);
}
@@ -4714,10 +4715,10 @@ int Client::lutime(const char *relpath, struct utimbuf *buf)
if (r < 0)
return r;
struct stat attr;
- attr.st_mtim.tv_sec = buf->modtime;
- attr.st_mtim.tv_nsec = 0;
- attr.st_atim.tv_sec = buf->actime;
- attr.st_atim.tv_nsec = 0;
+ stat_set_mtime_sec(&attr, buf->modtime);
+ stat_set_mtime_nsec(&attr, 0);
+ stat_set_atime_sec(&attr, buf->actime);
+ stat_set_atime_nsec(&attr, 0);
return _setattr(in, &attr, CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME);
}
diff --git a/src/include/stat.h b/src/include/stat.h
new file mode 100644
index 00000000000..67f943f5184
--- /dev/null
+++ b/src/include/stat.h
@@ -0,0 +1,145 @@
+#ifndef CEPH_STAT_H
+#define CEPH_STAT_H
+
+#include <acconfig.h>
+
+#include <sys/stat.h>
+
+/*
+ * Access time-related `struct stat` members.
+ *
+ * Note that for each of the stat member get/set functions below, setting a
+ * high-res value (stat_set_*_nsec) on a platform without high-res support is
+ * a no-op.
+ */
+
+#ifdef HAVE_STAT_TV_NSEC
+
+static inline uint32_t stat_get_mtime_nsec(struct stat *st)
+{
+ return st->st_mtim.tv_nsec;
+}
+
+static inline void stat_set_mtime_nsec(struct stat *st, uint32_t nsec)
+{
+ st->st_mtim.tv_nsec = nsec;
+}
+
+static inline uint32_t stat_get_atime_nsec(struct stat *st)
+{
+ return st->st_atim.tv_nsec;
+}
+
+static inline void stat_set_atime_nsec(struct stat *st, uint32_t nsec)
+{
+ st->st_atim.tv_nsec = nsec;
+}
+
+static inline uint32_t stat_get_ctime_nsec(struct stat *st)
+{
+ return st->st_ctim.tv_nsec;
+}
+
+static inline void stat_set_ctime_nsec(struct stat *st, uint32_t nsec)
+{
+ st->st_ctim.tv_nsec = nsec;
+}
+
+#elif defined(HAVE_STAT_ST_TIMESPEC)
+
+static inline uint32_t stat_get_mtime_nsec(struct stat *st)
+{
+ return st->st_mtimespec.tv_nsec;
+}
+
+static inline void stat_set_mtime_nsec(struct stat *st, uint32_t nsec)
+{
+ st->st_mtimespec.tv_nsec = nsec;
+}
+
+static inline uint32_t stat_get_atime_nsec(struct stat *st)
+{
+ return st->st_atimespec.tv_nsec;
+}
+
+static inline void stat_set_atime_nsec(struct stat *st, uint32_t nsec)
+{
+ st->st_atimespec.tv_nsec = nsec;
+}
+
+static inline uint32_t stat_get_ctime_nsec(struct stat *st)
+{
+ return st->st_ctimespec.tv_nsec;
+}
+
+static inline void stat_set_ctime_nsec(struct stat *st, uint32_t nsec)
+{
+ st->st_ctimespec.tv_nsec = nsec;
+}
+
+#else
+
+static inline uint32_t stat_get_mtime_nsec(struct stat *st)
+{
+ return 0;
+}
+
+static inline void stat_set_mtime_nsec(struct stat *st, uint32_t nsec)
+{
+}
+
+static inline uint32_t stat_get_atime_nsec(struct stat *st)
+{
+ return 0;
+}
+
+static inline void stat_set_atime_nsec(struct stat *st, uint32_t nsec)
+{
+}
+
+static inline uint32_t stat_get_ctime_nsec(struct stat *st)
+{
+ return 0;
+}
+
+static inline void stat_set_ctime_nsec(struct stat *st, uint32_t nsec)
+{
+}
+
+#endif
+
+/*
+ * Access second-resolution `struct stat` members.
+ */
+
+static inline uint32_t stat_get_mtime_sec(struct stat *st)
+{
+ return st->st_mtime;
+}
+
+static inline void stat_set_mtime_sec(struct stat *st, uint32_t sec)
+{
+ st->st_mtime = sec;
+}
+
+static inline uint32_t stat_get_atime_sec(struct stat *st)
+{
+ return st->st_atime;
+}
+
+static inline void stat_set_atime_sec(struct stat *st, uint32_t sec)
+{
+ st->st_atime = sec;
+}
+
+static inline uint32_t stat_get_ctime_sec(struct stat *st)
+{
+ return st->st_ctime;
+}
+
+static inline void stat_set_ctime_sec(struct stat *st, uint32_t sec)
+{
+ st->st_ctime = sec;
+}
+
+#endif