diff options
author | Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> | 2010-11-24 11:38:10 +0900 |
---|---|---|
committer | Venkateswararao Jujjuri (JV) <jvrao@linux.vnet.ibm.com> | 2010-12-02 16:08:40 -0800 |
commit | 38671423466875ecd848710cc1d7019448a6b145 (patch) | |
tree | 0f76c0f0ef78c7d4bcf71f8e7ca92204dcb31963 | |
parent | 0562c67432991d1cee442615d70fd39e638bec71 (diff) |
virtio-9p: fix build on !CONFIG_UTIMENSAT
This patch introduce a fallback mechanism for old systems that do not
support utimensat(). This fix build failure with following warnings:
hw/virtio-9p-local.c: In function 'local_utimensat':
hw/virtio-9p-local.c:479: warning: implicit declaration of function 'utimensat'
hw/virtio-9p-local.c:479: warning: nested extern declaration of 'utimensat'
and:
hw/virtio-9p.c: In function 'v9fs_setattr_post_chmod':
hw/virtio-9p.c:1410: error: 'UTIME_NOW' undeclared (first use in this function)
hw/virtio-9p.c:1410: error: (Each undeclared identifier is reported only once
hw/virtio-9p.c:1410: error: for each function it appears in.)
hw/virtio-9p.c:1413: error: 'UTIME_OMIT' undeclared (first use in this function)
hw/virtio-9p.c: In function 'v9fs_wstat_post_chmod':
hw/virtio-9p.c:2905: error: 'UTIME_OMIT' undeclared (first use in this function)
[NOTE: At this time virtio-9p is only user of utimensat(), and is available
only when host is linux and CONFIG_VIRTFS is defined. So there are
no similar warning for win32. Please provide a wrapper for win32 in
oslib-win32.c if new user really requires it.]
v5:
- Allow fallback on runtime
- Move qemu_utimensat() to oslib-posix.c
- Rebased on latest qemu.git
v4:
- Use tv_now.tv_usec
v3:
- Use better alternative handling for UTIME_NOW/OMIT
- Move qemu_utimensat() to cutils.c
V2:
- Introduce qemu_utimensat()
Acked-by: Chris Wright <chrisw@sous-sol.org>
Acked-by: M. Mohan Kumar <mohan@in.ibm.com>
Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
-rw-r--r-- | hw/virtio-9p-local.c | 4 | ||||
-rw-r--r-- | oslib-posix.c | 48 | ||||
-rw-r--r-- | qemu-os-posix.h | 12 |
3 files changed, 62 insertions, 2 deletions
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c index 656bfb375b..a8e7525bf6 100644 --- a/hw/virtio-9p-local.c +++ b/hw/virtio-9p-local.c @@ -480,9 +480,9 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp) } 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) diff --git a/oslib-posix.c b/oslib-posix.c index 6e9b0c3c13..7bc5f7cf09 100644 --- a/oslib-posix.c +++ b/oslib-posix.c @@ -107,3 +107,51 @@ int qemu_pipe(int pipefd[2]) return ret; } + +int qemu_utimensat(int dirfd, const char *path, const struct timespec *times, + int flags) +{ + struct timeval tv[2], tv_now; + struct stat st; + int i; +#ifdef CONFIG_UTIMENSAT + int ret; + + ret = utimensat(dirfd, path, times, flags); + if (ret != -1 || errno != ENOSYS) { + return ret; + } +#endif + /* Fallback: use utimes() instead of utimensat() */ + + /* happy if special cases */ + if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT) { + return 0; + } + if (times[0].tv_nsec == UTIME_NOW && times[1].tv_nsec == UTIME_NOW) { + return utimes(path, NULL); + } + + /* prepare for hard cases */ + if (times[0].tv_nsec == UTIME_NOW || times[1].tv_nsec == UTIME_NOW) { + gettimeofday(&tv_now, NULL); + } + if (times[0].tv_nsec == UTIME_OMIT || times[1].tv_nsec == UTIME_OMIT) { + stat(path, &st); + } + + for (i = 0; i < 2; i++) { + if (times[i].tv_nsec == UTIME_NOW) { + tv[i].tv_sec = tv_now.tv_sec; + tv[i].tv_usec = tv_now.tv_usec; + } else if (times[i].tv_nsec == UTIME_OMIT) { + tv[i].tv_sec = (i == 0) ? st.st_atime : st.st_mtime; + 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]); +} diff --git a/qemu-os-posix.h b/qemu-os-posix.h index 353f87813f..81fd9ab389 100644 --- a/qemu-os-posix.h +++ b/qemu-os-posix.h @@ -39,4 +39,16 @@ void os_setup_post(void); typedef struct timeval qemu_timeval; #define qemu_gettimeofday(tp) gettimeofday(tp, NULL) +#ifndef CONFIG_UTIMENSAT +#ifndef UTIME_NOW +# define UTIME_NOW ((1l << 30) - 1l) +#endif +#ifndef UTIME_OMIT +# define UTIME_OMIT ((1l << 30) - 2l) +#endif +#endif +typedef struct timespec qemu_timespec; +int qemu_utimensat(int dirfd, const char *path, const qemu_timespec *times, + int flags); + #endif |