@@ -479,10 +479,38 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
return -1;
}
+/* TODO: relocate this to proper file, and make it more generic */
+static int qemu_utimensat(int dirfd, const char *path,
+ const struct timespec *times, int flags)
+{
+#ifdef CONFIG_UTIMENSAT
+ return utimensat(dirfd, path, times, flags);
+#else
+ /*
+ * Fallback: use utimes() instead of utimensat().
+ * See commit 74bc02b2d2272dc88fb98d43e631eb154717f517 for known problem.
+ */
+ struct timeval tv[2];
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if (times[i].tv_nsec == UTIME_OMIT || times[i].tv_nsec == UTIME_NOW) {
+ tv[i].tv_sec = 0;
+ tv[i].tv_usec = 0;
+ } else {
+ tv[i].tv_sec = times[i].tv_sec;
+ tv[i].tv_usec = times[i].tv_nsec / 1000;
+ }
+ }
+
+ return utimes(path, &tv[0]);
+#endif
+}
+
static int local_utimensat(FsContext *s, const char *path,
- const struct timespec *buf)
+ const struct timespec *buf)
{
- return utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
+ return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, AT_SYMLINK_NOFOLLOW);
}
static int local_remove(FsContext *ctx, const char *path)
@@ -8,6 +8,16 @@
#include "file-op-9p.h"
+/* TODO: relocate this to proper file */
+#ifndef CONFIG_UTIMENSAT
+#ifndef UTIME_NOW
+# define UTIME_NOW ((1l << 30) - 1l)
+#endif
+#ifndef UTIME_OMIT
+# define UTIME_OMIT ((1l << 30) - 2l)
+#endif
+#endif
+
/* The feature bitmap for virtio 9P */
/* The mount point is specified in a config variable */
#define VIRTIO_9P_MOUNT_TAG 0