summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/common-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/common-utils.c')
-rw-r--r--libglusterfs/src/common-utils.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 51f97442fec..e18c97f5aa1 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -3806,7 +3806,11 @@ int
gf_set_timestamp (const char *src, const char* dest)
{
struct stat sb = {0, };
- struct timeval new_time[2] = {{0, },{0,}};
+#if defined(HAVE_UTIMENSAT)
+ struct timespec new_time[2] = { {0, }, {0, } };
+#else
+ struct timeval new_time[2] = { {0, }, {0, } };
+#endif
int ret = 0;
xlator_t *this = NULL;
@@ -3821,21 +3825,35 @@ gf_set_timestamp (const char *src, const char* dest)
LG_MSG_FILE_STAT_FAILED, "stat on %s", src);
goto out;
}
+ /* The granularity is nano seconds if `utimensat()` is available,
+ * and micro seconds otherwise.
+ */
+#if defined(HAVE_UTIMENSAT)
+ new_time[0].tv_sec = sb.st_atime;
+ new_time[0].tv_nsec = ST_ATIM_NSEC (&sb);
+
+ new_time[1].tv_sec = sb.st_mtime;
+ new_time[1].tv_nsec = ST_MTIM_NSEC (&sb);
+
+ /* dirfd = 0 is ignored because `dest` is an absolute path. */
+ ret = sys_utimensat (AT_FDCWD, dest, new_time, AT_SYMLINK_NOFOLLOW);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, errno,
+ LG_MSG_UTIMENSAT_FAILED, "utimensat on %s", dest);
+ }
+#else
new_time[0].tv_sec = sb.st_atime;
new_time[0].tv_usec = ST_ATIM_NSEC (&sb)/1000;
new_time[1].tv_sec = sb.st_mtime;
new_time[1].tv_usec = ST_MTIM_NSEC (&sb)/1000;
- /* The granularity is micro seconds as per the current
- * requiremnt. Hence using 'utimes'. This can be updated
- * to 'utimensat' if we need timestamp in nanoseconds.
- */
ret = sys_utimes (dest, new_time);
if (ret) {
gf_msg (this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED,
"utimes on %s", dest);
}
+#endif
out:
return ret;
}